Building Windows Ui With Wpf


Table of Contents
Mastering Windows Presentation Foundation
Credits
About the Author
About the Reviewer
Why subscribe?
Customer Feedback
Preface
What this book covers
What you need for this book
Who this book is for
Conventions
Reader feedback
Customer support
Downloading the example code
Downloading the color images of this book
Errata
Piracy
Questions
1. A Smarter Way of Working with WPF
What is MVVM and how does it help?
Models
View Models
Views
Data binding
So how does MVVM help?
Is there a downside?
Debunking the myth about code behind
Learning how to communicate again
Introducing the ICommand interface
Handling events in Attached Properties
Making use of delegates
Structuring the application code base
Summary
2. Debugging WPF Applications
Utilizing the Output window
Putting Presentation Trace Sources to work
Discovering inner exceptions
Debugging data bound values

Outputting values to UI controls
Catching changing Dependency Property values
Exploiting converters
Summary
3. Writing Custom Application Frameworks
What is an application framework?
Encapsulating common functionality
In base classes
Through interfaces
With Extension methods
In UI controls
With converters
Constructing a custom application framework
Separating the Data Access Layer
Providing services
Implementing Dependency Injection
Connecting Views with View Models
Summary
4. Becoming Proficient with Data Binding
Data binding basics
Binding path syntax
Escaping invalid characters
Exploring the Binding class
Directing data bound traffic
Binding to different sources
Binding with priority
Binding from within control templates
Binding source changes
Converting data bound values
Binding multiple sources to a single target property
Dependency Properties
Setting metadata
Declaring read-only Dependency Properties
Registering Attached Properties
Prioritizing value setting sources
Data templates
Taking complete control
Displaying hierarchical data
Data binding to enumeration collections
Summary
5. Using the Right Controls for the Job
Investigating the built-in controls
Inheriting framework abilities

Laying it on the line
Containing controls
Canvas
DockPanel
Grid
StackPanel
UniformGrid
WrapPanel
Providing custom layout behavior
Content controls
Presenting content
Items controls
Adorners
Modifying existing controls
Styling
Being resourceful
Merging resources
Triggering changes
Templating controls
Attaching properties
Combining controls
Creating custom controls
Summary
6. Mastering Practical Animations
Investigating timelines
Introducing key-frames
Telling stories
Controlling storyboards
Easing functions
Animating along a path
Creating everyday animations
Summary
7. Creating Visually Appealing User Interfaces
Styling applications consistently
Overriding default control styles
Using professional icons
Layering visuals
Throwing shadows
Declaring multiple borders
Reusing composite visuals
Reflecting light
Creating glowing effects
Putting it all together

Moving away from the ordinary
Casting reflections
Exploring borderless windows
Visualizing data
Livening up UI controls
Summary
8. Implementing Responsive Data Validation
Using validation rules - To do or not to do?
Getting to grips with validation interfaces
Implementing the IDataErrorInfo interface
Introducing the INotifyDataErrorInfo interface
Annotating data
Varying levels of validation
Incorporating multiple validation techniques
Customizing the error template
Avoiding UI-based validation errors
Amalgamating validation and visuals
Summary
9. Completing That Great User Experience
Providing user feedback
Utilizing multiple threads
Discovering the Async and Await keywords
Building asynchrony into our framework
Going the extra mile
Producing in-application help
Enabling user preferences
Extending common courtesies
Un-burdening the end user
Summary
10. Improving Application Performance
Leveraging the power of hardware rendering
Making more efficient resources
Freezing objects
Using the right controls for performance
Drawing conclusions
Imaging more efficiently
Enhancing the performance of textual output
Liking the linking
Data binding
Registering Dependency Properties
Binding to collections
Shrinking data objects
Virtualizing collections

Handling events
Summary
11. Deploying Your Masterpiece Application
Installing Windows applications
Utilizing ClickOnce functionality
Securing deployments
Isolating storage
Accessing application versions
Summary
12. What Next?
Turning attention to future projects
Improving our application framework
Logging errors
Using online resources

Mastering Windows Presentation
Foundation

Mastering Windows Presentation
Foundation
Copyright © 2017 Packt Publishing
All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or
transmitted in any form or by any means, without the prior written permission of the
publisher, except in the case of brief quotations embedded in critical articles or reviews.
Every effort has been made in the preparation of this book to ensure the accuracy of the
information presented. However, the information contained in this book is sold without
warranty, either express or implied. Neither the author, nor Packt Publishing, and its dealers
and distributors will be held liable for any damages caused or alleged to be caused directly
or indirectly by this book.
Packt Publishing has endeavored to provide trademark information about all of the
companies and products mentioned in this book by the appropriate use of capitals.
However, Packt Publishing cannot guarantee the accuracy of this information.
First published: February 2017
Production reference: 1130217
Published by Packt Publishing Ltd.
Livery Place
35 Livery Street
Birmingham
B3 2PB, UK.
ISBN 978-1-78588-300-2

Credits
Author
Copy Editor
Sheridan Yuen
Pranjali Chury
Reviewer
Project Coordinator
Alex Golesh
Vaidehi Sawant
Commissioning Editor
Proofreader
Edward Gordon
Safis Editing
Acquisition Editor
Indexer
Chaitanya Nair
Rekha Nair
Content Development Editor
Graphics
Zeeyan Pinheiro
Kirk D’Penha
Technical Editor
Production Coordinator
Kunal Chaudhari
Shantanu N. Zagade

About the Author
Sheridan Yuen is a Microsoft .NET MCTS and Oracle Java SCJP certified software
developer, living in London, England. His passion for coding made him stand out from the
crowd right from the start. From his second year onward at university, he was employed to
be a teaching assistant for the first year student coding workshops and has since returned
as a guest lecturer.
Among other prestigious positions, he was the primary software developer for the Ministry
of Sound group for four years, working on their main music business application,
responsible for creating their multi award winning albums. This application managed to
increase its users’ productivity by up to 80% in some cases.
In addition to this, he architected a unique ticket scanning application for their award winning
nightclub, making it the first club in the world to introduce scanned ticket entry across all
streams for their clients. Coming from a musical background and being a qualified audio
engineer, with experience of record production and digital audio, this post was a perfect
union.
He soon became a popular figure in the C# and WPF sections of the Stack Overflow,
“question and answer” website, being awarded enough reputation by the community
members to raise him to well within the top half percent of all users. While authoring this
book and other projects have kept him away for some time, he is keen to return to continue
to help new users to get to grips with WPF.
I would like to thank my long suffering girlfriend Jemma, who has regularly had to make
do without my company for the best part of a year, for her patience while I was composing
and writing this book and the many examples in it. I’d also like to thank Chaitanya from
Packt Publishing for convincing me to write this book in the first place and without who,
this book would not have been written.
Finally, I would like to thank Mary Thomson, Professor Sarah Barman and Professor
James Orwell in particular, from Kingston University, London, who inspired me to change
the direction of my previous career and planted the seed of curiosity that has taken me so
far. I would also like to thank James for encouraging me to move from the Bachelor’s
Degree course to the integrated Master’s Degree that I ended up gaining and for all of the
benefits that this brought with it.

About the Reviewer
Alex Golesh is an international expert in XAML-based technologies such as Universal
Windows Platform (Windows, Windows Phone, HoloLens, Xbox One), Xamarin.Forms,
WPF, and Silverlight. Also, Alex specializes in cloud-based solutions such as Microsoft
Azure. Alex developed training solutions for Microsoft Learning on Windows Phone and
Windows 8 and delivers workshops for developers and enterprises. Alex leads the
architecture and development process in multiple projects for his clients.

Did you know that Packt offers eBook versions of every book published, with PDF and
a print book customer, you are entitled to a discount on the eBook copy. Get in touch with
us at service@packtpub.com for more details.
a range of free newsletters and receive exclusive discounts and offers on Packt books and
eBooks.
Get the most in-demand software skills with Mapt. Mapt gives you full access to all Packt
books and video courses, as well as industry-leading tools to help you plan your personal
development and advance your career.
Why subscribe?
Fully searchable across every book published by Packt
Copy and paste, print, and bookmark content
On demand and accessible via a web browser

Customer Feedback
Thanks for purchasing this Packt book. At Packt, quality is at the heart of our editorial
process. To help us improve, please leave us an honest review on this book’s Amazon page
If you’d like to join our team of regular reviewers, you can email us at
customerreviews@packtpub.com. We award our regular reviewers with free eBooks and
videos in exchange for their valuable feedback. Help us be relentless in improving our
products!

Preface
While it can be easy to construct a basic form using WPF, it takes a lot more to fully
understand what WPF can do for us and how best to use it. It has a steep learning curve
and it can be difficult to comprehend this very different way of working. This book aims to
help you to get over that initial hill and continue to fully enable you to implement any given
requirement.
This book will start by providing you the foundation knowledge on how to improve your
workflow and what to do when you have problems. It will build upon this foundation by
introducing the base layer of the application that will serve all that comes after it. We will
then take a detour to cover data binding in detail.
The book will then turn to the User Interface (UI) and how to get the most out of the built-in
and custom WPF controls. It will make clear which customization methods are best to utilize
in a wide range of scenarios, avoiding the need to rewrite existing functionality. Other tips
and tricks will also be provided to enable you to create your own visually stunning UIs.
The final section of the book will introduce the concluding ways for you to polish your
applications, from adding practical animations and data validation, to improving application
performance. The book will end by explaining how to deploy the applications that you have
been working so hard on and discuss other things that you can now achieve with your new
found knowledge.

What this book covers
Chapter 1, A Smarter Way of Working with WPF, introduces the Model, View, View Model
(MVVM) software architectural pattern and the benefits of using it with WPF.
Chapter 2, Debugging WPF Applications, provides essential tips on various methods of
debugging WPF applications, ensuring the ability to iron out any problems that may occur.
Chapter 3, Writing Custom Application Frameworks, introduces the indispensable concept
of application frameworks, with early examples that will be built upon as the book
progresses. By the end of the book, you will have a fully functioning Framework with which
to build your applications upon.
Chapter 4, Becoming Proficient with Data Binding, demystifies data binding and clearly
demonstrates how to use it in a practical application. A plethora of examples will help you to
understand which binding syntax to use in any given situation and to be confident that their
bindings will work as expected.
Chapter 5, Using The Right Controls for The Job, explains which controls to use in
particular situations and describes the various ways to modify them when required. It
clearly outlines how to customize existing controls and how to create custom controls when
required.
Chapter 6, Mastering Practical Animations, explains the ins and outs of WPF Animations,
detailing lesser known functionality. It concludes with a number of ideas for practical
animations and continues to build upon the custom application framework.
Chapter 7, Creating Visually Stunning User Interfaces, offers advice for getting the most
out of the WPF visuals, while remaining practical, and provides handy tips on making
applications stand out from the crowd.
Chapter 8, Implementing Responsive Data Validation, presents a number of methods of
data validation to suit every situation and continues to build upon the custom application
framework. It covers full, partial, instant, and delayed validation and a variety of different
ways to display validation errors.
Chapter 9, Completing That Great User Experience, provides tips for creating applications
with a great user experience. Concepts introduced here, such as asynchronous data
access and keeping the end users well informed, will substantially improve the existing
custom application framework.
Chapter 10, Improving Application Performance, lists a number of ways to increase the
performance of WPF applications from freezing resources to implementing virtualization.
Readers that follow these tips and tricks can rest assured that their WPF applications will
perform as optimally as they can.
Chapter 11, Deploying Your Masterpiece Application, covers the final requirement for all
professional applications—deployment. It includes the older method of using the Windows
Installer software, along with the more common and up-to-date method of using ClickOnce
functionality.
Chapter 12, What Next?, summarizes what you have learned from this book and suggests
what you can do with many of your various new skills. It provides you with further ideas on
extending the application framework.


What you need for this book
As with all WPF development, you’ll need to have the .NET Framework and a version of
Microsoft’s Visual Studio integrated development environment software installed on your
computer.
You’ll be able to use versions as old as 2010, but in order to use the code in the book that
takes advantage of the latest .NET Framework improvements, you’ll need to use one of the
newer versions. Note that any edition of Visual Studio can be used, from the top of the line
Enterprise edition to the free Community (2015) edition.

Who this book is for
This book is for working developers with a basic to moderate level of knowledge about
Windows Presentation Foundation and for those interested in improving their practical day
to day WPF skills. It will also be of special interest to individuals wanting to know more
about application architecture and those wanting to improve the look of their user
interfaces.

Conventions
In this book, you will find a number of text styles that distinguish between different kinds of
information. Here are some examples of these styles and an explanation of their meaning.
Code words in text, database table names, folder names, filenames, file extensions,
pathnames, dummy URLs, user input, and Twitter handles are shown as follows: “There are
two other useful properties declared by the Grid class.”
A block of code is set as follows:
public string Name
{
get { return name; }
set
{
if (name != value)
{
name = value;
NotifyPropertyChanged(“Name”);
}
}
}
Any command-line input or output is written as follows:
System.Windows.Data Error: 17 : Cannot get ‘Item[]’ value (type
‘ValidationError’) from ‘(Validation.Errors)’ (type
‘ReadOnlyObservableCollection
1').</span></div>
<div style="position:absolute;left:52.98px;top:387.75px" class="cls_009"><span class="cls_009">BindingExpression:Path=(Validation.Errors)[0].ErrorContent;</span></div>
<div style="position:absolute;left:52.98px;top:401.25px" class="cls_009"><span class="cls_009">DataItem='TextBox' (Name=''); target element is 'TextBox'</span></div>
<div style="position:absolute;left:52.98px;top:415.50px" class="cls_009"><span class="cls_009">(Name='');</span></div>
<div style="position:absolute;left:52.98px;top:429.75px" class="cls_009"><span class="cls_009">target property is 'ToolTip' (type 'Object')</span></div>
<div style="position:absolute;left:52.98px;top:444.00px" class="cls_009"><span class="cls_009">ArgumentOutOfRangeException:'System.ArgumentOutOfRangeException:</span></div>
<div style="position:absolute;left:52.98px;top:458.25px" class="cls_009"><span class="cls_009">Specified argument was out of the range of valid values.</span></div>
<div style="position:absolute;left:5.00px;top:479.25px" class="cls_005"><span class="cls_005">New terms </span><span class="cls_004">and </span><span class="cls_005">important words </span><span class="cls_004">are shown in bold. Words that you see on the screen,</span></div>
<div style="position:absolute;left:5.00px;top:498.00px" class="cls_004"><span class="cls_004">for example, in menus or dialog boxes, appear in the text like this: "The </span><span class="cls_005">Cancel</span><span class="cls_004"> button has</span></div>
<div style="position:absolute;left:5.00px;top:516.75px" class="cls_004"><span class="cls_004">been declared in the second row and column."</span></div>
<div style="position:absolute;left:17.00px;top:534.75px" class="cls_010"><span class="cls_010">Note</span></div>
<div style="position:absolute;left:17.00px;top:560.25px" class="cls_004"><span class="cls_004">Warnings or important notes appear in a box like this.</span></div>
<div style="position:absolute;left:17.00px;top:579.00px" class="cls_010"><span class="cls_010">Tip</span></div>
<div style="position:absolute;left:17.00px;top:604.50px" class="cls_004"><span class="cls_004">Tips and tricks appear like this.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:14436px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background020.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_008"><span class="cls_008">Reader feedback</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">Feedback from our readers is always welcome. Let us know what you think about this</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">book-what you liked or disliked. Reader feedback is important for us as it helps us develop</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">titles that you will really get the most out of. To send us general feedback, simply e-</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">mail </span><span class="cls_007">feedback@packtpub.com</span><span class="cls_004">, and mention the book's title in the subject of your message. If</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">there is a topic that you have expertise in and you are interested in either writing or</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">contributing to a book, see our author guide at </span><A HREF="http://www.packtpub.com/authors">www.packtpub.com/authors</A> </span><span class="cls_004">.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:15238px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background021.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_008"><span class="cls_008">Customer support</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">Now that you are the proud owner of a Packt book, we have a number of things to help you</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">to get the most from your purchase.</span></div>
<div style="position:absolute;left:5.00px;top:75.01px" class="cls_011"><span class="cls_011">Downloading the example code</span></div>
<div style="position:absolute;left:5.00px;top:105.00px" class="cls_004"><span class="cls_004">You can download the example code files for this book from your account at</span></div>
<div style="position:absolute;left:5.00px;top:123.00px" class="cls_015"><span class="cls_015"> </span><A HREF="http://www.packtpub.com">http://www.packtpub.com</A> <span class="cls_004">. If you purchased this book elsewhere, you can visit</span></div>
<div style="position:absolute;left:5.00px;top:141.00px" class="cls_015"><span class="cls_015"> </span><A HREF="http://www.packtpub.com/support">http://www.packtpub.com/support</A> <span class="cls_004"> and register to have the files e-mailed directly to you.</span></div>
<div style="position:absolute;left:5.00px;top:159.00px" class="cls_004"><span class="cls_004">You can download the code files by following these steps:</span></div>
<div style="position:absolute;left:13.25px;top:177.00px" class="cls_004"><span class="cls_004">1. Log in or register to our website using your e-mail address and password.</span></div>
<div style="position:absolute;left:13.25px;top:195.00px" class="cls_004"><span class="cls_004">2. Hover the mouse pointer on the </span><span class="cls_005">SUPPORT</span><span class="cls_004"> tab at the top.</span></div>
<div style="position:absolute;left:13.25px;top:213.75px" class="cls_004"><span class="cls_004">3. Click on </span><span class="cls_005">Code Downloads & Errata</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:13.25px;top:232.50px" class="cls_004"><span class="cls_004">4. Enter the name of the book in the </span><span class="cls_005">Search</span><span class="cls_004"> box.</span></div>
<div style="position:absolute;left:13.25px;top:251.25px" class="cls_004"><span class="cls_004">5. Select the book for which you're looking to download the code files.</span></div>
<div style="position:absolute;left:13.25px;top:269.25px" class="cls_004"><span class="cls_004">6. Choose from the drop-down menu where you purchased this book from.</span></div>
<div style="position:absolute;left:13.25px;top:287.25px" class="cls_004"><span class="cls_004">7. Click on </span><span class="cls_005">Code Download</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:306.00px" class="cls_004"><span class="cls_004">Once the file is downloaded, please make sure that you unzip or extract the folder using the</span></div>
<div style="position:absolute;left:5.00px;top:324.00px" class="cls_004"><span class="cls_004">latest version of:</span></div>
<div style="position:absolute;left:34.99px;top:342.00px" class="cls_004"><span class="cls_004">WinRAR / 7-Zip for Windows</span></div>
<div style="position:absolute;left:34.99px;top:360.00px" class="cls_004"><span class="cls_004">Zipeg / iZip / UnRarX for Mac</span></div>
<div style="position:absolute;left:34.99px;top:378.00px" class="cls_004"><span class="cls_004">7-Zip / PeaZip for Linux</span></div>
<div style="position:absolute;left:5.00px;top:396.00px" class="cls_004"><span class="cls_004">The code bundle for the book is also hosted on GitHub at</span></div>
<div style="position:absolute;left:5.00px;top:414.00px" class="cls_015"><span class="cls_015"> </span><A HREF="https://github.com/PacktPublishing/Mastering-Windows-Presentation-Foundation">https://github.com/PacktPublishing/Mastering-Windows-Presentation-Foundation</A> <span class="cls_004">. We also</span></div>
<div style="position:absolute;left:5.00px;top:432.00px" class="cls_004"><span class="cls_004">have other code bundles from our rich catalog of books and videos available at</span></div>
<div style="position:absolute;left:5.00px;top:450.00px" class="cls_015"><span class="cls_015"> </span><A HREF="https://github.com/PacktPublishing/">https://github.com/PacktPublishing/</A> <span class="cls_004">. Check them out!</span></div>
<div style="position:absolute;left:5.00px;top:467.26px" class="cls_011"><span class="cls_011">Downloading the color images of this book</span></div>
<div style="position:absolute;left:5.00px;top:497.25px" class="cls_004"><span class="cls_004">We also provide you with a PDF file that has color images of the screenshots/diagrams</span></div>
<div style="position:absolute;left:5.00px;top:515.25px" class="cls_004"><span class="cls_004">used in this book. The color images will help you better understand the changes in the</span></div>
<div style="position:absolute;left:5.00px;top:533.25px" class="cls_004"><span class="cls_004">output. You can download this file from</span></div>
<div style="position:absolute;left:5.00px;top:551.25px" class="cls_015"><span class="cls_015"> </span><A HREF="https://www.packtpub.com/sites/default/files/downloads/MasteringWindowsPresentationFoundation_ColorImages.pdf">https://www.packtpub.com/sites/default/files/downloads/MasteringWindowsPresentationFou</A> </div>
<div style="position:absolute;left:5.00px;top:568.51px" class="cls_011"><span class="cls_011">Errata</span></div>
<div style="position:absolute;left:5.00px;top:598.50px" class="cls_004"><span class="cls_004">Although we have taken every care to ensure the accuracy of our content, mistakes do</span></div>
<div style="position:absolute;left:5.00px;top:616.50px" class="cls_004"><span class="cls_004">happen. If you find a mistake in one of our books-maybe a mistake in the text or the code-</span></div>
<div style="position:absolute;left:5.00px;top:634.50px" class="cls_004"><span class="cls_004">we would be grateful if you could report this to us. By doing so, you can save other readers</span></div>
<div style="position:absolute;left:5.00px;top:652.50px" class="cls_004"><span class="cls_004">from frustration and help us improve subsequent versions of this book. If you find any</span></div>
<div style="position:absolute;left:5.00px;top:670.50px" class="cls_004"><span class="cls_004">errata, please report them by visiting </span><A HREF="http://www.packtpub.com/submit-errata">http://www.packtpub.com/submit-errata</A> </span><span class="cls_004">, selecting</span></div>
<div style="position:absolute;left:5.00px;top:688.50px" class="cls_004"><span class="cls_004">your book, clicking on the </span><span class="cls_005">Errata Submission Form</span><span class="cls_004"> link, and entering the details of your</span></div>
<div style="position:absolute;left:5.00px;top:707.25px" class="cls_004"><span class="cls_004">errata. Once your errata are verified, your submission will be accepted and the errata will</span></div>
<div style="position:absolute;left:5.00px;top:725.25px" class="cls_004"><span class="cls_004">be uploaded to our website or added to any list of existing errata under the Errata section</span></div>
<div style="position:absolute;left:5.00px;top:743.25px" class="cls_004"><span class="cls_004">of that title.</span></div>
<div style="position:absolute;left:5.00px;top:761.25px" class="cls_004"><span class="cls_004">To view the previously submitted errata, go to</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:16040px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background022.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_015"><span class="cls_015">h</span><A HREF="https://www.packtpub.com/books/content/support">ttps://www.packtpub.com/books/content/support</A> <span class="cls_004"> and enter the name of the book in the</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">search field. The required information will appear under the </span><span class="cls_005">Errata</span><span class="cls_004"> section.</span></div>
<div style="position:absolute;left:5.00px;top:39.76px" class="cls_011"><span class="cls_011">Piracy</span></div>
<div style="position:absolute;left:5.00px;top:69.75px" class="cls_004"><span class="cls_004">Piracy of copyrighted material on the Internet is an ongoing problem across all media. At</span></div>
<div style="position:absolute;left:5.00px;top:87.75px" class="cls_004"><span class="cls_004">Packt, we take the protection of our copyright and licenses very seriously. If you come</span></div>
<div style="position:absolute;left:5.00px;top:105.75px" class="cls_004"><span class="cls_004">across any illegal copies of our works in any form on the Internet, please provide us with</span></div>
<div style="position:absolute;left:5.00px;top:123.75px" class="cls_004"><span class="cls_004">the location address or website name immediately so that we can pursue a remedy.</span></div>
<div style="position:absolute;left:5.00px;top:141.75px" class="cls_004"><span class="cls_004">Please contact us at </span><span class="cls_007">copyright@packtpub.com</span><span class="cls_004"> with a link to the suspected pirated material.</span></div>
<div style="position:absolute;left:5.00px;top:159.75px" class="cls_004"><span class="cls_004">We appreciate your help in protecting our authors and our ability to bring you valuable</span></div>
<div style="position:absolute;left:5.00px;top:177.75px" class="cls_004"><span class="cls_004">content.</span></div>
<div style="position:absolute;left:5.00px;top:195.01px" class="cls_011"><span class="cls_011">Questions</span></div>
<div style="position:absolute;left:5.00px;top:225.00px" class="cls_004"><span class="cls_004">If you have a problem with any aspect of this book, you can contact us</span></div>
<div style="position:absolute;left:5.00px;top:243.00px" class="cls_004"><span class="cls_004">at </span><span class="cls_007">questions@packtpub.com</span><span class="cls_004">, and we will do our best to address the problem.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:16842px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background023.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_002"><span class="cls_002">Chapter 1. A Smarter Way of Working with</span></div>
<div style="position:absolute;left:5.00px;top:39.01px" class="cls_002"><span class="cls_002">WPF</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">When </span><span class="cls_005">Windows Presentation Foundation</span><span class="cls_004"> (</span><span class="cls_005">WPF</span><span class="cls_004">) was first released as part of the .NET</span></div>
<div style="position:absolute;left:5.00px;top:94.50px" class="cls_004"><span class="cls_004">Framework version 3.0 in 2006, it was billed as the future of desktop application </span><span class="cls_005">Graphical</span></div>
<div style="position:absolute;left:5.00px;top:113.25px" class="cls_005"><span class="cls_005">User Interface</span><span class="cls_004"> (</span><span class="cls_005">GUI</span><span class="cls_004">) languages and supporters claimed that it would put an end to the</span></div>
<div style="position:absolute;left:5.00px;top:132.00px" class="cls_004"><span class="cls_004">previous GUI technology, Windows Forms. However, as time passed, it has fallen far short</span></div>
<div style="position:absolute;left:5.00px;top:150.00px" class="cls_004"><span class="cls_004">of this claim.</span></div>
<div style="position:absolute;left:5.00px;top:168.00px" class="cls_004"><span class="cls_004">There are three main reasons that WPF has not taken off as widely as previously expected.</span></div>
<div style="position:absolute;left:5.00px;top:186.00px" class="cls_004"><span class="cls_004">The first reason has nothing to do with WPF and stems from the recent push to host</span></div>
<div style="position:absolute;left:5.00px;top:204.00px" class="cls_004"><span class="cls_004">everything in the cloud and having web interfaces rather than desktop applications. The</span></div>
<div style="position:absolute;left:5.00px;top:222.00px" class="cls_004"><span class="cls_004">second reason relates to the very steep learning curve and the very different way of</span></div>
<div style="position:absolute;left:5.00px;top:240.00px" class="cls_004"><span class="cls_004">working that is required to master WPF.</span></div>
<div style="position:absolute;left:5.00px;top:258.00px" class="cls_004"><span class="cls_004">The last reason is that it is not a very efficient language and if a WPF application has lots of</span></div>
<div style="position:absolute;left:5.00px;top:276.00px" class="cls_004"><span class="cls_004">'bells and whistles' in, then either the client computers will need to have additional RAM</span></div>
<div style="position:absolute;left:5.00px;top:294.00px" class="cls_004"><span class="cls_004">and/or graphics cards installed, or they could face a slow and stuttering user experience.</span></div>
<div style="position:absolute;left:5.00px;top:312.00px" class="cls_004"><span class="cls_004">This explains why many companies that make use of WPF today are in the finance industry,</span></div>
<div style="position:absolute;left:5.00px;top:330.00px" class="cls_004"><span class="cls_004">where they can afford to upgrade all users' computers to be able to run their applications</span></div>
<div style="position:absolute;left:5.00px;top:348.00px" class="cls_004"><span class="cls_004">optimally. This book will aim to make WPF more accessible to the rest of us by providing</span></div>
<div style="position:absolute;left:5.00px;top:366.00px" class="cls_004"><span class="cls_004">practical tips and tricks to help build our real-world applications more easily and more</span></div>
<div style="position:absolute;left:5.00px;top:384.00px" class="cls_004"><span class="cls_004">efficiently.</span></div>
<div style="position:absolute;left:5.00px;top:402.00px" class="cls_004"><span class="cls_004">One of the simplest changes with the biggest workflow improvements that we can make to</span></div>
<div style="position:absolute;left:5.00px;top:420.00px" class="cls_004"><span class="cls_004">improve the way we work with WPF is to follow the MVVM software architectural pattern. It</span></div>
<div style="position:absolute;left:5.00px;top:438.00px" class="cls_004"><span class="cls_004">describes how we can organize our classes to make our applications more maintainable,</span></div>
<div style="position:absolute;left:5.00px;top:456.00px" class="cls_004"><span class="cls_004">testable, and generally simpler to understand. In this chapter, we will take a closer look at</span></div>
<div style="position:absolute;left:5.00px;top:474.00px" class="cls_004"><span class="cls_004">this pattern and discover how it can help us to improve our applications.</span></div>
<div style="position:absolute;left:5.00px;top:492.00px" class="cls_004"><span class="cls_004">After discovering what MVVM is and what its benefits are, we'll learn several new ways to</span></div>
<div style="position:absolute;left:5.00px;top:510.00px" class="cls_004"><span class="cls_004">communicate between the various components in this new environment. We'll then focus on</span></div>
<div style="position:absolute;left:5.00px;top:528.00px" class="cls_004"><span class="cls_004">the physical structure of the code base in a typical MVVM application and investigate a</span></div>
<div style="position:absolute;left:5.00px;top:546.00px" class="cls_004"><span class="cls_004">variety of alternative arrangements.</span></div>
<div style="position:absolute;left:5.00px;top:563.26px" class="cls_008"><span class="cls_008">What is MVVM and how does it help?</span></div>
<div style="position:absolute;left:5.00px;top:600.00px" class="cls_005"><span class="cls_005">Model-View-View Model</span><span class="cls_004"> (</span><span class="cls_005">MVVM</span><span class="cls_004">) is a software architectural pattern that was famously</span></div>
<div style="position:absolute;left:5.00px;top:618.75px" class="cls_004"><span class="cls_004">introduced by John Gossman on his blog back in 2005 and is now commonly used when</span></div>
<div style="position:absolute;left:5.00px;top:636.75px" class="cls_004"><span class="cls_004">developing WPF applications. Its main purpose is to provide a </span><span class="cls_006">Separation of Concerns</span></div>
<div style="position:absolute;left:5.00px;top:655.50px" class="cls_004"><span class="cls_004">between the business model, the </span><span class="cls_005">User Interface</span><span class="cls_004"> (</span><span class="cls_005">UI</span><span class="cls_004">), and the business logic. It does this</span></div>
<div style="position:absolute;left:5.00px;top:674.25px" class="cls_004"><span class="cls_004">by dividing them into three distinct types of core components: Models, Views, and View</span></div>
<div style="position:absolute;left:5.00px;top:692.25px" class="cls_004"><span class="cls_004">Models. Let's take a look at how they are arranged and what each of these components</span></div>
<div style="position:absolute;left:5.00px;top:710.25px" class="cls_004"><span class="cls_004">represent.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:17644px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background024.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:146.25px" class="cls_004"><span class="cls_004">As we can see here, the </span><span class="cls_005">View Models</span><span class="cls_004"> component sits between the </span><span class="cls_005">Models</span><span class="cls_004"> and the </span><span class="cls_005">Views</span></div>
<div style="position:absolute;left:5.00px;top:165.00px" class="cls_004"><span class="cls_004">and provides two-way access to each of them. It should be noted at this point that there</span></div>
<div style="position:absolute;left:5.00px;top:183.00px" class="cls_004"><span class="cls_004">should be no direct relationship between the </span><span class="cls_005">Views</span><span class="cls_004"> and </span><span class="cls_005">Models</span><span class="cls_004"> components and only loose</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">connections between the other components. Let's now take a closer look at what each of</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">these components represent.</span></div>
<div style="position:absolute;left:5.00px;top:237.01px" class="cls_011"><span class="cls_011">Models</span></div>
<div style="position:absolute;left:5.00px;top:267.00px" class="cls_004"><span class="cls_004">Unlike the other MVVM components, the Model constituent comprises of a number of</span></div>
<div style="position:absolute;left:5.00px;top:285.00px" class="cls_004"><span class="cls_004">elements. It encompasses the business data model along with its related validation logic</span></div>
<div style="position:absolute;left:5.00px;top:303.00px" class="cls_004"><span class="cls_004">and also the </span><span class="cls_005">Data Access Layer</span><span class="cls_004"> (</span><span class="cls_005">DAL</span><span class="cls_004">), or data repositories, that provide the application</span></div>
<div style="position:absolute;left:5.00px;top:321.75px" class="cls_004"><span class="cls_004">with data access and persistence.</span></div>
<div style="position:absolute;left:5.00px;top:339.75px" class="cls_004"><span class="cls_004">The data model represents the classes that hold the data in the application. They typically</span></div>
<div style="position:absolute;left:5.00px;top:357.75px" class="cls_004"><span class="cls_004">mirror the columns in the database more or less, although it is common that they are</span></div>
<div style="position:absolute;left:5.00px;top:375.75px" class="cls_004"><span class="cls_004">hierarchical in form, and so may require joins to be performed in the data source in order to</span></div>
<div style="position:absolute;left:5.00px;top:393.75px" class="cls_004"><span class="cls_004">fully populate them. One alternative would be to design the data model classes to fit the</span></div>
<div style="position:absolute;left:5.00px;top:411.75px" class="cls_004"><span class="cls_004">requirements in the UI, but either way, the business logic or validation rules will typically</span></div>
<div style="position:absolute;left:5.00px;top:429.75px" class="cls_004"><span class="cls_004">reside in the same project as the data model.</span></div>
<div style="position:absolute;left:5.00px;top:447.75px" class="cls_004"><span class="cls_004">The code that is used to interface with whatever data persistence technology is used in our</span></div>
<div style="position:absolute;left:5.00px;top:465.75px" class="cls_004"><span class="cls_004">application is also included within the Models component of the pattern. Care should be</span></div>
<div style="position:absolute;left:5.00px;top:483.75px" class="cls_004"><span class="cls_004">taken when it comes to organizing this component in the code base, as there are a number</span></div>
<div style="position:absolute;left:5.00px;top:501.75px" class="cls_004"><span class="cls_004">of issues to take into consideration. We'll investigate this further in a while, but for now, let's</span></div>
<div style="position:absolute;left:5.00px;top:519.75px" class="cls_004"><span class="cls_004">continue to find out more about the components in this pattern.</span></div>
<div style="position:absolute;left:5.00px;top:537.01px" class="cls_011"><span class="cls_011">View Models</span></div>
<div style="position:absolute;left:5.00px;top:567.00px" class="cls_004"><span class="cls_004">The View Models can be explained easily; each View Model provides its associated View</span></div>
<div style="position:absolute;left:5.00px;top:585.00px" class="cls_004"><span class="cls_004">with all of the data and functionality that it requires. In some ways, they can be considered</span></div>
<div style="position:absolute;left:5.00px;top:603.00px" class="cls_004"><span class="cls_004">to be similar to the old Windows Forms code behind files, except that they have no direct</span></div>
<div style="position:absolute;left:5.00px;top:621.00px" class="cls_004"><span class="cls_004">relationship with the View that they are serving. A better analogy, if you're familiar with</span></div>
<div style="position:absolute;left:5.00px;top:639.00px" class="cls_004"><span class="cls_004">MVC, would be that they are similar to the Controllers in the </span><span class="cls_005">Model-View-Controller</span><span class="cls_004"> (</span><span class="cls_005">MVC</span><span class="cls_004">)</span></div>
<div style="position:absolute;left:5.00px;top:657.75px" class="cls_004"><span class="cls_004">software architectural pattern. In fact, in his blog, John describes the MVVM pattern as</span></div>
<div style="position:absolute;left:5.00px;top:675.75px" class="cls_004"><span class="cls_004">being a variation of the MVC pattern.</span></div>
<div style="position:absolute;left:5.00px;top:693.75px" class="cls_004"><span class="cls_004">They have two-way connections with the Model component in order to access and update</span></div>
<div style="position:absolute;left:5.00px;top:711.75px" class="cls_004"><span class="cls_004">the data that the Views require, and often, they transform that data in some way to make it</span></div>
<div style="position:absolute;left:5.00px;top:729.75px" class="cls_004"><span class="cls_004">easier to display and interact with in the UI. They also have two-way connections with the</span></div>
<div style="position:absolute;left:5.00px;top:747.75px" class="cls_004"><span class="cls_004">Views through data binding and property change notification. In short, View Models form</span></div>
<div style="position:absolute;left:5.00px;top:765.75px" class="cls_004"><span class="cls_004">the bridge between the Model and the View, which otherwise have no connection to each</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:18446px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background025.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">other.</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">However, it should be noted that the View Models are only loosely connected to the Views</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">and Model components through their data binding and interfaces. The beauty of this pattern</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">enables each element to be able to function independently from each other.</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">To maintain the separation between the View Models and the View, we avoid declaring any</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">properties of UI-related types in the View Model. We don't want any references to UI-</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">related DLLs in our View Models project, and so we make use of custom </span><span class="cls_007">IValueConverter</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">implementations to convert them to primitive types. For example, we might convert</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_007"><span class="cls_007">Visibility</span><span class="cls_004"> objects from the UI to plain </span><span class="cls_007">bool</span><span class="cls_004"> values or convert the selection of some</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">colored </span><span class="cls_007">Brush</span><span class="cls_004"> objects to an </span><span class="cls_007">Enum</span><span class="cls_004"> instance that is safe to use in the View Model.</span></div>
<div style="position:absolute;left:5.00px;top:183.01px" class="cls_011"><span class="cls_011">Views</span></div>
<div style="position:absolute;left:5.00px;top:213.00px" class="cls_004"><span class="cls_004">The Views define the appearance and layout of the UI. They typically connect with a View</span></div>
<div style="position:absolute;left:5.00px;top:231.00px" class="cls_004"><span class="cls_004">Model through the use of their </span><span class="cls_007">DataContext</span><span class="cls_004"> property and display the data that it supplies.</span></div>
<div style="position:absolute;left:5.00px;top:249.00px" class="cls_004"><span class="cls_004">They expose the functionality provided by the View Model by connecting its commands to</span></div>
<div style="position:absolute;left:5.00px;top:267.00px" class="cls_004"><span class="cls_004">the UI controls that the users interact with.</span></div>
<div style="position:absolute;left:5.00px;top:285.00px" class="cls_004"><span class="cls_004">In general, the basic rule of thumb is that each View has one associated View Model. This</span></div>
<div style="position:absolute;left:5.00px;top:303.00px" class="cls_004"><span class="cls_004">does not mean that a View cannot data bind to more than one data source or that we</span></div>
<div style="position:absolute;left:5.00px;top:321.00px" class="cls_004"><span class="cls_004">cannot reuse View Models. It simply means that, in general, if we have a class called</span></div>
<div style="position:absolute;left:5.00px;top:339.00px" class="cls_007"><span class="cls_007">SecurityView</span><span class="cls_004">, it is more than likely that we'll also have an instance of a class named</span></div>
<div style="position:absolute;left:5.00px;top:357.00px" class="cls_007"><span class="cls_007">SecurityViewModel</span><span class="cls_004"> that will be set as the value of that View's </span><span class="cls_007">DataContext</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:5.00px;top:374.26px" class="cls_011"><span class="cls_011">Data binding</span></div>
<div style="position:absolute;left:5.00px;top:404.25px" class="cls_004"><span class="cls_004">One often overlooked aspect of the MVVM pattern is its requirement for data binding. We</span></div>
<div style="position:absolute;left:5.00px;top:422.25px" class="cls_004"><span class="cls_004">could not have the full Separation of Concerns without it, as there would be no easy way of</span></div>
<div style="position:absolute;left:5.00px;top:440.25px" class="cls_004"><span class="cls_004">communicating between the Views and View Models. The XAML markup, data binding</span></div>
<div style="position:absolute;left:5.00px;top:458.25px" class="cls_004"><span class="cls_004">classes, and </span><span class="cls_007">ICommand</span><span class="cls_004"> and </span><span class="cls_007">INotifyPropertyChanged</span><span class="cls_004"> interfaces are the main tools in WPF</span></div>
<div style="position:absolute;left:5.00px;top:476.25px" class="cls_004"><span class="cls_004">that provide this functionality.</span></div>
<div style="position:absolute;left:5.00px;top:494.25px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">ICommand</span><span class="cls_004"> interface is how commanding is implemented in the .NET Framework. It</span></div>
<div style="position:absolute;left:5.00px;top:512.25px" class="cls_004"><span class="cls_004">provides behavior that implements and even extends the ever useful Command pattern, in</span></div>
<div style="position:absolute;left:5.00px;top:530.25px" class="cls_004"><span class="cls_004">which an object encapsulates everything needed to perform an action. Most of the UI</span></div>
<div style="position:absolute;left:5.00px;top:548.25px" class="cls_004"><span class="cls_004">controls in WPF have </span><span class="cls_007">Command</span><span class="cls_004"> properties that we can use to connect them to the</span></div>
<div style="position:absolute;left:5.00px;top:566.25px" class="cls_004"><span class="cls_004">functionality that the commands provide.</span></div>
<div style="position:absolute;left:5.00px;top:584.25px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">INotifyPropertyChanged</span><span class="cls_004"> interface is used to notify binding clients that property values</span></div>
<div style="position:absolute;left:5.00px;top:602.25px" class="cls_004"><span class="cls_004">have been changed. For example, if we had a </span><span class="cls_007">User</span><span class="cls_004"> object and it had a </span><span class="cls_007">Name</span><span class="cls_004"> property, then</span></div>
<div style="position:absolute;left:5.00px;top:620.25px" class="cls_004"><span class="cls_004">our </span><span class="cls_007">User</span><span class="cls_004"> class would be responsible for raising the </span><span class="cls_007">PropertyChanged</span><span class="cls_004"> event of the</span></div>
<div style="position:absolute;left:5.00px;top:638.25px" class="cls_007"><span class="cls_007">INotifyPropertyChanged</span><span class="cls_004"> interface, specifying the name of the property each time its value</span></div>
<div style="position:absolute;left:5.00px;top:656.25px" class="cls_004"><span class="cls_004">was changed. We'll look much deeper into all of this later, but now let's see how the</span></div>
<div style="position:absolute;left:5.00px;top:674.25px" class="cls_004"><span class="cls_004">arrangement of these components help us.</span></div>
<div style="position:absolute;left:5.00px;top:691.51px" class="cls_011"><span class="cls_011">So how does MVVM help?</span></div>
<div style="position:absolute;left:5.00px;top:721.50px" class="cls_004"><span class="cls_004">One major benefit of adopting MVVM is that it provides the crucial Separation of Concerns</span></div>
<div style="position:absolute;left:5.00px;top:739.50px" class="cls_004"><span class="cls_004">between the business model, the UI, and the business logic. This enables us to do several</span></div>
<div style="position:absolute;left:5.00px;top:757.50px" class="cls_004"><span class="cls_004">things. It frees the View Models from the Models, both the business model and the data</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:19248px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background026.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">persistence technology. This in turn enables us to reuse the business model in other</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">applications and swap out the DAL and replace it with a mock data layer so that we can</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">effectively test the functionality in our view models without requiring any kind of real data</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">connection.</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">It also disconnects the Views from the View logic that they require, as this is provided by</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">the View Models. This allows us to run each component independently, which has the</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">advantage of enabling one team to work on designing the Views, while another team works</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">on the View Models. Having parallel work streams enables companies to benefit from vastly</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">reduced production times.</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">Furthermore, this separation also makes it easier for us to swap the Views for a different</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">technology without needing to change our Model code. We may well need to change some</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">aspects of the View Models, for example, the new technology used for the Views may not</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">support the </span><span class="cls_007">ICommand</span><span class="cls_004"> interface, but in principal, the amount of code that we would need to</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">change would be fairly minimal.</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">The simplicity of the MVVM pattern also makes WPF easier to comprehend. Knowing that</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">each View has a View Model that provides it with all the data and functionality that it</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">requires means that we always know where to look when we want to find where our data</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">bound properties have been declared.</span></div>
<div style="position:absolute;left:5.00px;top:327.01px" class="cls_011"><span class="cls_011">Is there a downside?</span></div>
<div style="position:absolute;left:5.00px;top:357.00px" class="cls_004"><span class="cls_004">There are, however, a few drawbacks to using MVVM, and it will not help us in every</span></div>
<div style="position:absolute;left:5.00px;top:375.00px" class="cls_004"><span class="cls_004">situation. The main downside to implementing MVVM is that it adds a certain level of</span></div>
<div style="position:absolute;left:5.00px;top:393.00px" class="cls_004"><span class="cls_004">complexity to our applications. First, there's the data binding, which can take some time to</span></div>
<div style="position:absolute;left:5.00px;top:411.00px" class="cls_004"><span class="cls_004">master. Also, depending on your version of Visual Studio, data binding errors may only</span></div>
<div style="position:absolute;left:5.00px;top:429.00px" class="cls_004"><span class="cls_004">appear at runtime and can be very tricky to track down.</span></div>
<div style="position:absolute;left:5.00px;top:447.00px" class="cls_004"><span class="cls_004">Then, there are the different ways to communicate between the Views and View Models</span></div>
<div style="position:absolute;left:5.00px;top:465.00px" class="cls_004"><span class="cls_004">that we need to understand. Commanding and handling events in an unusual way takes a</span></div>
<div style="position:absolute;left:5.00px;top:483.00px" class="cls_004"><span class="cls_004">while to get used to. Having to discover the optimal arrangement of all the required</span></div>
<div style="position:absolute;left:5.00px;top:501.00px" class="cls_004"><span class="cls_004">components in the code base also takes time. So, there is a steep learning curve to climb</span></div>
<div style="position:absolute;left:5.00px;top:519.00px" class="cls_004"><span class="cls_004">before we can become competent at implementing MVVM for sure. This book will cover all</span></div>
<div style="position:absolute;left:5.00px;top:537.00px" class="cls_004"><span class="cls_004">of these areas in detail and attempt to lessen the gradient of that learning curve.</span></div>
<div style="position:absolute;left:5.00px;top:555.00px" class="cls_004"><span class="cls_004">However, even when we are well practiced at the pattern, there are still occasional</span></div>
<div style="position:absolute;left:5.00px;top:573.00px" class="cls_004"><span class="cls_004">situations when it wouldn't make sense to implement MVVM. One example would be if our</span></div>
<div style="position:absolute;left:5.00px;top:591.00px" class="cls_004"><span class="cls_004">application was going to be very small, it would be unlikely that we would want to have unit</span></div>
<div style="position:absolute;left:5.00px;top:609.00px" class="cls_004"><span class="cls_004">tests for it or swap out any of its components. It would, therefore, be impractical to go</span></div>
<div style="position:absolute;left:5.00px;top:627.00px" class="cls_004"><span class="cls_004">through the added complexity of implementing the pattern when the benefits of the</span></div>
<div style="position:absolute;left:5.00px;top:645.00px" class="cls_004"><span class="cls_004">Separation of Concerns that it provides were not required.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:20050px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background027.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_008"><span class="cls_008">Debunking the myth about code behind</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">One of the great misconceptions about MVVM is that we should avoid putting any code into</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">the code behind files of our Views. While there is some truth to this, it is certainly not true in</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">all situations. If we think logically for a moment, we already know that the main reason to</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">use MVVM is to take advantage of the Separation of Concerns that its architecture</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">provides. Part of this separates the business functionality in the View Model from the user</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">interface-related code in the Views. Therefore, the rule should really be we should avoid</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">putting any business logic into the code behind files of our Views.</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">Keeping this in mind, let's look at what code we might want to put into the code behind file</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">of a View. The most likely suspects would be some UI-related code, maybe handling a</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">particular event, or launching a child window of some kind. In these cases, using the code</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">behind file would be absolutely fine. We have no business-related code here, and so we</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">have no need to separate it from the other UI-related code.</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">On the other hand, if we had written some business-related code in a View's code behind</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">file, then how could we test it? In this case, we would have no way to separate this from</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">the View, no longer have our Separation of Concerns and, therefore, would have broken our</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">implementation of MVVM. So in cases like this, the myth is no longer a myth... it is good</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_004"><span class="cls_004">advice.</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_004"><span class="cls_004">However, even in cases like this where we want to call some business-related code from a</span></div>
<div style="position:absolute;left:5.00px;top:363.75px" class="cls_004"><span class="cls_004">View, it </span><span class="cls_006">is</span><span class="cls_004"> possible to achieve without breaking any rules. As long as our business code</span></div>
<div style="position:absolute;left:5.00px;top:382.50px" class="cls_004"><span class="cls_004">resides in a View Model, it can be tested through that View Model, so it's not so important</span></div>
<div style="position:absolute;left:5.00px;top:400.50px" class="cls_004"><span class="cls_004">where it is called from during runtime. Understanding that we can always access the View</span></div>
<div style="position:absolute;left:5.00px;top:418.50px" class="cls_004"><span class="cls_004">Model that is data bound to a View's </span><span class="cls_007">DataContext</span><span class="cls_004"> property, let's look at this simple</span></div>
<div style="position:absolute;left:5.00px;top:436.50px" class="cls_004"><span class="cls_004">example:</span></div>
<div style="position:absolute;left:52.98px;top:459.75px" class="cls_007"><span class="cls_007">private void Button_Click(object sender, RoutedEventArgs e)</span></div>
<div style="position:absolute;left:52.98px;top:473.25px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:486.75px" class="cls_007"><span class="cls_007">UserViewModel viewModel = (UserViewModel)DataContext;</span></div>
<div style="position:absolute;left:67.97px;top:500.25px" class="cls_007"><span class="cls_007">viewModel.PerformSomeAction();</span></div>
<div style="position:absolute;left:52.98px;top:513.75px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:534.00px" class="cls_004"><span class="cls_004">Now, there are some who would balk at this code example, as they correctly believe that</span></div>
<div style="position:absolute;left:5.00px;top:552.00px" class="cls_004"><span class="cls_004">Views should not know anything about their related View Models. This code effectively ties</span></div>
<div style="position:absolute;left:5.00px;top:570.00px" class="cls_004"><span class="cls_004">this View Model to this View. If we wanted to change the UI layer in our application at some</span></div>
<div style="position:absolute;left:5.00px;top:588.00px" class="cls_004"><span class="cls_004">point or have designers work on the View, then this code would cause us a problem.</span></div>
<div style="position:absolute;left:5.00px;top:606.00px" class="cls_004"><span class="cls_004">However, we need to be realistic... what is the likelihood that we will really need do that?</span></div>
<div style="position:absolute;left:5.00px;top:624.00px" class="cls_004"><span class="cls_004">If it is likely, then we really shouldn't put this code into the code behind file and instead</span></div>
<div style="position:absolute;left:5.00px;top:642.00px" class="cls_004"><span class="cls_004">handle the event by wrapping it in an Attached Property, and we'll see an example of this in</span></div>
<div style="position:absolute;left:5.00px;top:660.00px" class="cls_004"><span class="cls_004">the next section. However, if it is not at all likely, then there is really no problem with putting</span></div>
<div style="position:absolute;left:5.00px;top:678.00px" class="cls_004"><span class="cls_004">it there. Let's follow rules when they make sense for us to follow them rather than blindly</span></div>
<div style="position:absolute;left:5.00px;top:696.00px" class="cls_004"><span class="cls_004">sticking to them because somebody in a different scenario said they were a good idea.</span></div>
<div style="position:absolute;left:5.00px;top:714.00px" class="cls_004"><span class="cls_004">One other situation when we can ignore this 'No code behind' rule is when writing self-</span></div>
<div style="position:absolute;left:5.00px;top:732.00px" class="cls_004"><span class="cls_004">contained controls based on the </span><span class="cls_007">UserControl</span><span class="cls_004"> class. In these cases, the code behind files</span></div>
<div style="position:absolute;left:5.00px;top:750.00px" class="cls_004"><span class="cls_004">are often used for defining Dependency Properties and/or handling UI events and for</span></div>
<div style="position:absolute;left:5.00px;top:768.00px" class="cls_004"><span class="cls_004">implementing general UI functionality. Remember though, if these controls are implementing</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:20852px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background028.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">some business-related functionality, we should write that into a View Model and call it from</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">the control so that it can still be tested.</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">There is definitely perfect sense in the general idea of avoiding writing business-related</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">code in the code behind files of our Views and we should always try to do so. However, we</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">now hopefully understand the reasoning behind this idea and can use our logic to determine</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">whether it is ok to do it or not in each particular case that may arise.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:21654px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background029.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_008"><span class="cls_008">Learning how to communicate again</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">As we tend not to handle UI events directly, when using MVVM, we need alternative ways</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">to implement the same functionality that they provide. Different methods are required to</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">reproduce the functionality of different events. For example, the functionality of the</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_007"><span class="cls_007">SelectionChanged</span><span class="cls_004"> event of a collection control is typically reproduced by data binding a</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">View Model property to the </span><span class="cls_007">SelectedItem</span><span class="cls_004"> property of the collection control.</span></div>
<div style="position:absolute;left:52.98px;top:135.00px" class="cls_007"><span class="cls_007"><ListBox ItemsSource="{Binding Items}"</span></div>
<div style="position:absolute;left:67.97px;top:148.50px" class="cls_007"><span class="cls_007">SelectedItem="{Binding CurrentItem}" /></span></div>
<div style="position:absolute;left:5.00px;top:168.75px" class="cls_004"><span class="cls_004">In this example, the setter of the </span><span class="cls_007">CurrentItem</span><span class="cls_004"> property will get called by the WPF</span></div>
<div style="position:absolute;left:5.00px;top:186.75px" class="cls_004"><span class="cls_004">Framework each time a new item is selected from the </span><span class="cls_007">ListBox</span><span class="cls_004">. Therefore, instead of</span></div>
<div style="position:absolute;left:5.00px;top:204.75px" class="cls_004"><span class="cls_004">handling the </span><span class="cls_007">SelectionChanged</span><span class="cls_004"> event in the code behind, we can call any method directly</span></div>
<div style="position:absolute;left:5.00px;top:222.75px" class="cls_004"><span class="cls_004">from the property setter in the View Model:</span></div>
<div style="position:absolute;left:52.98px;top:246.00px" class="cls_007"><span class="cls_007">public TypeOfObject CurrentItem</span></div>
<div style="position:absolute;left:52.98px;top:259.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:273.00px" class="cls_007"><span class="cls_007">get { return currentItem; }</span></div>
<div style="position:absolute;left:67.97px;top:286.50px" class="cls_007"><span class="cls_007">set</span></div>
<div style="position:absolute;left:67.97px;top:300.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:313.50px" class="cls_007"><span class="cls_007">currentItem = value;</span></div>
<div style="position:absolute;left:82.97px;top:327.00px" class="cls_007"><span class="cls_007">DoSomethingWithTheNewlySelectedItem(currentItem);</span></div>
<div style="position:absolute;left:67.97px;top:340.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:354.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:374.25px" class="cls_004"><span class="cls_004">Note that we need to keep any methods that we call from data bound property setters from</span></div>
<div style="position:absolute;left:5.00px;top:392.25px" class="cls_004"><span class="cls_004">doing too much, as the time that it takes to execute them could negatively affect the</span></div>
<div style="position:absolute;left:5.00px;top:410.25px" class="cls_004"><span class="cls_004">performance when entering data. However, in this example, we would typically use this</span></div>
<div style="position:absolute;left:5.00px;top:428.25px" class="cls_004"><span class="cls_004">method to start an asynchronous data access function using a value from the current item</span></div>
<div style="position:absolute;left:5.00px;top:446.25px" class="cls_004"><span class="cls_004">or alter the value of another property in the View Model.</span></div>
<div style="position:absolute;left:5.00px;top:464.25px" class="cls_004"><span class="cls_004">Many other UI events can be replaced with some form of </span><span class="cls_007">Trigger</span><span class="cls_004"> in the XAML markup</span></div>
<div style="position:absolute;left:5.00px;top:482.25px" class="cls_004"><span class="cls_004">directly. For example, imagine that we had an </span><span class="cls_007">Image</span><span class="cls_004"> element that was set as the </span><span class="cls_007">Content</span></div>
<div style="position:absolute;left:5.00px;top:500.25px" class="cls_004"><span class="cls_004">property value of a </span><span class="cls_007">Button</span><span class="cls_004"> control and that we wanted the </span><span class="cls_007">Image</span><span class="cls_004"> element to be semi-</span></div>
<div style="position:absolute;left:5.00px;top:518.25px" class="cls_004"><span class="cls_004">transparent when the </span><span class="cls_007">Button</span><span class="cls_004"> was disabled. Instead of handling the</span></div>
<div style="position:absolute;left:5.00px;top:536.25px" class="cls_007"><span class="cls_007">UIElement.IsEnabledChanged</span><span class="cls_004"> event in the code behind file, we could write a </span><span class="cls_007">DataTrigger</span><span class="cls_004"> in</span></div>
<div style="position:absolute;left:5.00px;top:554.25px" class="cls_004"><span class="cls_004">a </span><span class="cls_007">Style</span><span class="cls_004"> that we could apply to the </span><span class="cls_007">Image</span><span class="cls_004"> element:</span></div>
<div style="position:absolute;left:52.98px;top:577.50px" class="cls_007"><span class="cls_007"><Style x:Key="ImageInButtonStyle" TargetType="{x:Type Image}"></span></div>
<div style="position:absolute;left:67.97px;top:591.00px" class="cls_007"><span class="cls_007"><Setter Property="Opacity" Value="1.0" /></span></div>
<div style="position:absolute;left:67.97px;top:604.50px" class="cls_007"><span class="cls_007"><Style.Triggers></span></div>
<div style="position:absolute;left:82.97px;top:618.00px" class="cls_007"><span class="cls_007"><DataTrigger Binding="{Binding IsEnabled,</span></div>
<div style="position:absolute;left:97.96px;top:631.50px" class="cls_007"><span class="cls_007">RelativeSource={RelativeSource FindAncestor,</span></div>
<div style="position:absolute;left:97.96px;top:645.00px" class="cls_007"><span class="cls_007">AncestorType={x:Type Button}}, FallbackValue=False}"</span></div>
<div style="position:absolute;left:97.96px;top:658.50px" class="cls_007"><span class="cls_007">Value="False"></span></div>
<div style="position:absolute;left:97.96px;top:672.00px" class="cls_007"><span class="cls_007"><Setter Property="Opacity" Value="0.5" /></span></div>
<div style="position:absolute;left:82.97px;top:685.50px" class="cls_007"><span class="cls_007"></DataTrigger></span></div>
<div style="position:absolute;left:67.97px;top:699.00px" class="cls_007"><span class="cls_007"></Style.Triggers></span></div>
<div style="position:absolute;left:52.98px;top:712.50px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:5.00px;top:732.75px" class="cls_004"><span class="cls_004">Binding syntax will be covered in detail in </span><span class="cls_015">Chapter 4</span><span class="cls_004">, </span><span class="cls_006">Becoming Proficient With Data</span></div>
<div style="position:absolute;left:5.00px;top:751.50px" class="cls_006"><span class="cls_006">Binding</span><span class="cls_004">, but in short, the binding in this </span><span class="cls_007">DataTrigger</span><span class="cls_004"> is specifying the target as the</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:22456px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background030.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_007"><span class="cls_007">IsEnabled</span><span class="cls_004"> property of the ancestor (or parent) of the </span><span class="cls_007">Image</span><span class="cls_004"> element with a type of </span><span class="cls_007">Button</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">When this binding target has a value of </span><span class="cls_007">False</span><span class="cls_004">, the </span><span class="cls_007">Opacity</span><span class="cls_004"> property of the </span><span class="cls_007">Image</span><span class="cls_004"> will be set</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">to </span><span class="cls_007">0.5</span><span class="cls_004"> and set back to its original value when the target property value is </span><span class="cls_007">True</span><span class="cls_004">. Therefore,</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">Image</span><span class="cls_004"> element in our </span><span class="cls_007">Button</span><span class="cls_004"> will become semi-transparent when the </span><span class="cls_007">Button</span><span class="cls_004"> is disabled.</span></div>
<div style="position:absolute;left:5.00px;top:75.01px" class="cls_011"><span class="cls_011">Introducing the ICommand interface</span></div>
<div style="position:absolute;left:5.00px;top:105.00px" class="cls_004"><span class="cls_004">When it comes to button clicks in WPF and MVVM, instead of handling the well-known</span></div>
<div style="position:absolute;left:5.00px;top:123.00px" class="cls_007"><span class="cls_007">Click</span><span class="cls_004"> event, we typically use some form of command that implements the </span><span class="cls_007">ICommand</span></div>
<div style="position:absolute;left:5.00px;top:141.00px" class="cls_004"><span class="cls_004">interface. Let's take a look at an example of a basic standard command:</span></div>
<div style="position:absolute;left:52.98px;top:164.25px" class="cls_007"><span class="cls_007">using System;</span></div>
<div style="position:absolute;left:52.98px;top:177.75px" class="cls_007"><span class="cls_007">using System.Windows.Forms;</span></div>
<div style="position:absolute;left:52.98px;top:191.25px" class="cls_007"><span class="cls_007">using System.Windows.Input;</span></div>
<div style="position:absolute;left:52.98px;top:218.25px" class="cls_007"><span class="cls_007">public class TestCommand : ICommand</span></div>
<div style="position:absolute;left:52.98px;top:231.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:245.25px" class="cls_007"><span class="cls_007">public event EventHandler CanExecuteChanged;</span></div>
<div style="position:absolute;left:67.97px;top:272.25px" class="cls_007"><span class="cls_007">public void Execute(object parameter)</span></div>
<div style="position:absolute;left:67.97px;top:285.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:299.25px" class="cls_007"><span class="cls_007">MessageBox.Show("You executed a command");</span></div>
<div style="position:absolute;left:67.97px;top:312.75px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:339.75px" class="cls_007"><span class="cls_007">public bool CanExecute(object parameter)</span></div>
<div style="position:absolute;left:67.97px;top:353.25px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:366.75px" class="cls_007"><span class="cls_007">return true;</span></div>
<div style="position:absolute;left:67.97px;top:380.25px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:393.75px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:17.00px;top:414.00px" class="cls_010"><span class="cls_010">Tip</span></div>
<div style="position:absolute;left:17.00px;top:439.50px" class="cls_004"><span class="cls_004">Please note that in this book, we will display code with two-space tabs, instead of the</span></div>
<div style="position:absolute;left:17.00px;top:457.50px" class="cls_004"><span class="cls_004">more commonly used four-space tabs, in order to enable more characters of each code</span></div>
<div style="position:absolute;left:17.00px;top:475.50px" class="cls_004"><span class="cls_004">snippet to fit onto each line.</span></div>
<div style="position:absolute;left:5.00px;top:494.25px" class="cls_004"><span class="cls_004">We can see that it has an </span><span class="cls_007">Execute</span><span class="cls_004"> method, where the functionality that the command</span></div>
<div style="position:absolute;left:5.00px;top:512.25px" class="cls_004"><span class="cls_004">provides is performed. The </span><span class="cls_007">CanExecute</span><span class="cls_004"> method is called by the </span><span class="cls_007">CommandManager</span><span class="cls_004"> at various</span></div>
<div style="position:absolute;left:5.00px;top:530.25px" class="cls_004"><span class="cls_004">points over time, when it believes that the output value may have changed. We'll cover this</span></div>
<div style="position:absolute;left:5.00px;top:548.25px" class="cls_004"><span class="cls_004">in more detail later, but basically, raising the </span><span class="cls_007">CanExecuteChanged</span><span class="cls_004"> event is one of the ways to</span></div>
<div style="position:absolute;left:5.00px;top:566.25px" class="cls_004"><span class="cls_004">trigger the </span><span class="cls_007">CommandManager</span><span class="cls_004"> to do this. The output of the </span><span class="cls_007">CanExecute</span><span class="cls_004"> method specifies</span></div>
<div style="position:absolute;left:5.00px;top:584.25px" class="cls_004"><span class="cls_004">whether the </span><span class="cls_007">Execute</span><span class="cls_004"> method can be called or not.</span></div>
<div style="position:absolute;left:5.00px;top:602.25px" class="cls_004"><span class="cls_004">You can imagine how cumbersome it would be if we had to create one of these classes for</span></div>
<div style="position:absolute;left:5.00px;top:620.25px" class="cls_004"><span class="cls_004">every action that we needed to implement. Furthermore, there is no context of where the</span></div>
<div style="position:absolute;left:5.00px;top:638.25px" class="cls_004"><span class="cls_004">command was called from other than the single command parameter. This means that if we</span></div>
<div style="position:absolute;left:5.00px;top:656.25px" class="cls_004"><span class="cls_004">wanted the command to add an item into a collection, we would have to put both the</span></div>
<div style="position:absolute;left:5.00px;top:674.25px" class="cls_004"><span class="cls_004">collection and the item to add into another object so that they could both be passed through</span></div>
<div style="position:absolute;left:5.00px;top:692.25px" class="cls_004"><span class="cls_004">the single input parameter.</span></div>
<div style="position:absolute;left:5.00px;top:710.25px" class="cls_004"><span class="cls_004">When using MVVM, rather than implementing the commands in the standard way, we tend</span></div>
<div style="position:absolute;left:5.00px;top:728.25px" class="cls_004"><span class="cls_004">to use a single, reusable implementation that allows us to handle actions with standard</span></div>
<div style="position:absolute;left:5.00px;top:746.25px" class="cls_004"><span class="cls_004">methods directly in the View Model. This enables us to use commands without having to</span></div>
<div style="position:absolute;left:5.00px;top:764.25px" class="cls_004"><span class="cls_004">create a separate class for each one. There are a number of variations of this command,</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:23258px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background031.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">but its simplest form is shown here:</span></div>
<div style="position:absolute;left:52.98px;top:27.00px" class="cls_007"><span class="cls_007">using System;</span></div>
<div style="position:absolute;left:52.98px;top:40.50px" class="cls_007"><span class="cls_007">using System.Windows.Input;</span></div>
<div style="position:absolute;left:52.98px;top:67.50px" class="cls_007"><span class="cls_007">public class ActionCommand : ICommand</span></div>
<div style="position:absolute;left:52.98px;top:81.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:94.50px" class="cls_007"><span class="cls_007">private readonly Action<object> action;</span></div>
<div style="position:absolute;left:67.97px;top:108.00px" class="cls_007"><span class="cls_007">private readonly Predicate<object> canExecute;</span></div>
<div style="position:absolute;left:67.97px;top:135.00px" class="cls_007"><span class="cls_007">public ActionCommand(Action<object> action) : this(action, null)</span></div>
<div style="position:absolute;left:52.98px;top:148.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:148.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:175.50px" class="cls_007"><span class="cls_007">public ActionCommand(Action<object> action,</span></div>
<div style="position:absolute;left:82.97px;top:189.00px" class="cls_007"><span class="cls_007">Predicate<object> canExecute)</span></div>
<div style="position:absolute;left:67.97px;top:202.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:216.00px" class="cls_007"><span class="cls_007">this.action = action;</span></div>
<div style="position:absolute;left:82.97px;top:229.50px" class="cls_007"><span class="cls_007">this.canExecute = canExecute;</span></div>
<div style="position:absolute;left:67.97px;top:243.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:270.00px" class="cls_007"><span class="cls_007">public event EventHandler CanExecuteChanged</span></div>
<div style="position:absolute;left:67.97px;top:283.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:297.00px" class="cls_007"><span class="cls_007">add { CommandManager.RequerySuggested += value; }</span></div>
<div style="position:absolute;left:82.97px;top:310.50px" class="cls_007"><span class="cls_007">remove { CommandManager.RequerySuggested -= value; }</span></div>
<div style="position:absolute;left:67.97px;top:324.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:351.00px" class="cls_007"><span class="cls_007">public bool CanExecute(object parameter)</span></div>
<div style="position:absolute;left:67.97px;top:364.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:378.00px" class="cls_007"><span class="cls_007">return canExecute == null ? true : canExecute(parameter);</span></div>
<div style="position:absolute;left:67.97px;top:391.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:418.50px" class="cls_007"><span class="cls_007">public void Execute(object parameter)</span></div>
<div style="position:absolute;left:67.97px;top:432.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:445.50px" class="cls_007"><span class="cls_007">action(parameter);</span></div>
<div style="position:absolute;left:67.97px;top:459.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:472.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:492.75px" class="cls_004"><span class="cls_004">This is typically used in the View Model classes, as shown in the following example, where</span></div>
<div style="position:absolute;left:5.00px;top:510.75px" class="cls_004"><span class="cls_004">the command functionality comes from the </span><span class="cls_007">Save</span><span class="cls_004"> method and the </span><span class="cls_007">bool</span><span class="cls_004"> return value of the</span></div>
<div style="position:absolute;left:5.00px;top:528.75px" class="cls_007"><span class="cls_007">CanSave</span><span class="cls_004"> method determines whether the command can execute or not:</span></div>
<div style="position:absolute;left:52.98px;top:552.00px" class="cls_007"><span class="cls_007">public ICommand SaveCommand</span></div>
<div style="position:absolute;left:52.98px;top:565.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:579.00px" class="cls_007"><span class="cls_007">get { return new ActionCommand(action => Save(),</span></div>
<div style="position:absolute;left:82.97px;top:592.50px" class="cls_007"><span class="cls_007">canExecute => CanSave()); }</span></div>
<div style="position:absolute;left:52.98px;top:606.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:626.25px" class="cls_004"><span class="cls_004">A safer way to ensure that the command is never called </span><span class="cls_006">by code</span><span class="cls_004"> when the </span><span class="cls_007">CanExecute</span></div>
<div style="position:absolute;left:5.00px;top:645.00px" class="cls_004"><span class="cls_004">condition is not satisfied would be to make this alteration; however, please note that the</span></div>
<div style="position:absolute;left:5.00px;top:663.00px" class="cls_007"><span class="cls_007">CommandManager</span><span class="cls_004"> will always perform this check before calling any commands anyway:</span></div>
<div style="position:absolute;left:52.98px;top:686.25px" class="cls_007"><span class="cls_007">public void Execute(object parameter)</span></div>
<div style="position:absolute;left:52.98px;top:699.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:713.25px" class="cls_007"><span class="cls_007">if (CanExecute(parameter)) action(parameter);</span></div>
<div style="position:absolute;left:52.98px;top:726.75px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:747.00px" class="cls_004"><span class="cls_004">Full credit for this custom command should go to Josh Smith, as his </span><span class="cls_007">RelayCommand</span><span class="cls_004"> class</span></div>
<div style="position:absolute;left:5.00px;top:765.00px" class="cls_004"><span class="cls_004">was the first implementation like this that I came across, although there are several</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:24060px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background032.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">variations to be found online. The beauty of this particular implementation should not be</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">underestimated. Not only is it simple, elegant, and saves us from writing large amounts of</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">code, but it also makes testing our functionality much easier, as our command code can</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">now be defined right in our View Models.</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">action</span><span class="cls_004"> parameter of type </span><span class="cls_007">Action<object></span><span class="cls_004"> will hold the reference to the method that</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">will be called when the command is executed and the </span><span class="cls_007">object</span><span class="cls_004"> generic parameter relates to</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">the optionally used command parameter. The </span><span class="cls_007">canExecute</span><span class="cls_004"> parameter of type</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_007"><span class="cls_007">Predicate<object></span><span class="cls_004"> will hold the reference to the method that will be called to verify</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">whether the command can be executed or not and its </span><span class="cls_007">object</span><span class="cls_004"> generic parameter relates to</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">the optionally used command parameter again.</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">CanExecuteChanged</span><span class="cls_004"> event should be raised whenever the </span><span class="cls_007">canExecute</span><span class="cls_004"> parameter value</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">changes. It is typically handled by command sources, such as the </span><span class="cls_007">Button</span><span class="cls_004"> control, to set</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">their </span><span class="cls_007">IsEnabled</span><span class="cls_004"> property value appropriately. When a command source receives a</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">notification that this event has been raised, it will call the </span><span class="cls_007">ICommand.CanExecute</span><span class="cls_004"> method to</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">check the new value. Therefore, when a command can execute, its data bound control will</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">be enabled and when it can't, its data bound control will be disabled.</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">CommandManager.RequerySuggested</span><span class="cls_004"> event will be raised when the </span><span class="cls_007">CommandManager</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">detects a change in the UI that could reflect on whether a command could execute or not.</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_004"><span class="cls_004">For example, this could be due to a user interaction, such as the selection of an item in a</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_004"><span class="cls_004">collection or some other change in focus. Therefore, connecting one to the other seems to</span></div>
<div style="position:absolute;left:5.00px;top:363.75px" class="cls_004"><span class="cls_004">be a logical thing to do. In fact, an example of this is actually found in the source code of</span></div>
<div style="position:absolute;left:5.00px;top:381.75px" class="cls_004"><span class="cls_004">the .NET </span><span class="cls_007">RoutedCommand</span><span class="cls_004"> class. We'll look at this </span><span class="cls_007">ActionCommand</span><span class="cls_004"> again and in more detail in</span></div>
<div style="position:absolute;left:5.00px;top:399.75px" class="cls_015"><span class="cls_015">Chapter 3</span><span class="cls_004">, </span><span class="cls_006">Writing Custom Application Frameworks</span><span class="cls_004">, but for now, let's move on to the next</span></div>
<div style="position:absolute;left:5.00px;top:418.50px" class="cls_004"><span class="cls_004">method of communication.</span></div>
<div style="position:absolute;left:5.00px;top:435.76px" class="cls_011"><span class="cls_011">Handling events in Attached Properties</span></div>
<div style="position:absolute;left:5.00px;top:465.75px" class="cls_004"><span class="cls_004">There is one way to handle events in WPF without having to resort to writing code in the</span></div>
<div style="position:absolute;left:5.00px;top:483.75px" class="cls_004"><span class="cls_004">code behind file of a View. Using Attached Properties, we can encapsulate the handling of</span></div>
<div style="position:absolute;left:5.00px;top:501.75px" class="cls_004"><span class="cls_004">events and effectively expose their behavior using properties that we can data bind to in our</span></div>
<div style="position:absolute;left:5.00px;top:519.75px" class="cls_004"><span class="cls_004">Views. Let's take a look at a simple example using the </span><span class="cls_007">PreviewKeyDown</span><span class="cls_004"> event:</span></div>
<div style="position:absolute;left:52.98px;top:543.00px" class="cls_007"><span class="cls_007">public static DependencyProperty OnEnterKeyDownProperty =</span></div>
<div style="position:absolute;left:67.97px;top:556.50px" class="cls_007"><span class="cls_007">DependencyProperty.RegisterAttached("OnEnterKeyDown",</span></div>
<div style="position:absolute;left:67.97px;top:570.00px" class="cls_007"><span class="cls_007">typeof(ICommand), typeof(TextBoxProperties),</span></div>
<div style="position:absolute;left:67.97px;top:583.50px" class="cls_007"><span class="cls_007">new PropertyMetadata(OnOnEnterKeyDownChanged));</span></div>
<div style="position:absolute;left:52.98px;top:610.50px" class="cls_007"><span class="cls_007">public static ICommand GetOnEnterKeyDown(DependencyObject</span></div>
<div style="position:absolute;left:52.98px;top:624.00px" class="cls_007"><span class="cls_007">dependencyObject)</span></div>
<div style="position:absolute;left:52.98px;top:637.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:651.00px" class="cls_007"><span class="cls_007">return</span></div>
<div style="position:absolute;left:52.98px;top:664.50px" class="cls_007"><span class="cls_007">(ICommand)dependencyObject.GetValue(OnEnterKeyDownProperty);</span></div>
<div style="position:absolute;left:52.98px;top:678.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:705.00px" class="cls_007"><span class="cls_007">public static void SetOnEnterKeyDown(DependencyObject</span></div>
<div style="position:absolute;left:52.98px;top:718.50px" class="cls_007"><span class="cls_007">dependencyObject,</span></div>
<div style="position:absolute;left:67.97px;top:732.00px" class="cls_007"><span class="cls_007">ICommand value)</span></div>
<div style="position:absolute;left:52.98px;top:745.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:759.00px" class="cls_007"><span class="cls_007">dependencyObject.SetValue(OnEnterKeyDownProperty, value);</span></div>
<div style="position:absolute;left:52.98px;top:772.50px" class="cls_007"><span class="cls_007">}</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:24862px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background033.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:16.50px" class="cls_007"><span class="cls_007">public static void OnOnEnterKeyDownChanged(</span></div>
<div style="position:absolute;left:67.97px;top:30.00px" class="cls_007"><span class="cls_007">DependencyObject dependencyObject,</span></div>
<div style="position:absolute;left:67.97px;top:43.50px" class="cls_007"><span class="cls_007">DependencyPropertyChangedEventArgs e)</span></div>
<div style="position:absolute;left:52.98px;top:57.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:70.50px" class="cls_007"><span class="cls_007">TextBox textBox = (TextBox)dependencyObject;</span></div>
<div style="position:absolute;left:67.97px;top:84.00px" class="cls_007"><span class="cls_007">if (e.OldValue == null && e.NewValue != null)</span></div>
<div style="position:absolute;left:82.97px;top:97.50px" class="cls_007"><span class="cls_007">textBox.PreviewKeyDown += TextBox_OnEnterKeyDown;</span></div>
<div style="position:absolute;left:67.97px;top:111.00px" class="cls_007"><span class="cls_007">else if (e.OldValue != null && e.NewValue == null)</span></div>
<div style="position:absolute;left:82.97px;top:124.50px" class="cls_007"><span class="cls_007">textBox.PreviewKeyDown -= TextBox_OnEnterKeyDown;</span></div>
<div style="position:absolute;left:52.98px;top:138.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:165.00px" class="cls_007"><span class="cls_007">private static void TextBox_OnEnterKeyDown(object sender,</span></div>
<div style="position:absolute;left:52.98px;top:178.50px" class="cls_007"><span class="cls_007">KeyEventArgs e)</span></div>
<div style="position:absolute;left:52.98px;top:192.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:205.50px" class="cls_007"><span class="cls_007">if (e.Key == Key.Enter || e.Key == Key.Return)</span></div>
<div style="position:absolute;left:67.97px;top:219.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:232.50px" class="cls_007"><span class="cls_007">TextBox textBox = sender as TextBox;</span></div>
<div style="position:absolute;left:82.97px;top:246.00px" class="cls_007"><span class="cls_007">ICommand command = GetOnEnterKeyDown(textBox);</span></div>
<div style="position:absolute;left:82.97px;top:259.50px" class="cls_007"><span class="cls_007">if (command != null && command.CanExecute(textBox))</span></div>
<div style="position:absolute;left:97.96px;top:273.00px" class="cls_007"><span class="cls_007">command.Execute(textBox);</span></div>
<div style="position:absolute;left:67.97px;top:286.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:300.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:320.25px" class="cls_004"><span class="cls_004">As can be seen in this example, the event is handled by attaching an event handler in the</span></div>
<div style="position:absolute;left:5.00px;top:338.25px" class="cls_004"><span class="cls_004">normal way, except that all relating code is encapsulated within the class that declares the</span></div>
<div style="position:absolute;left:5.00px;top:356.25px" class="cls_004"><span class="cls_004">Attached Property. Let's take a closer look. First, we declare an Attached Property named</span></div>
<div style="position:absolute;left:5.00px;top:374.25px" class="cls_007"><span class="cls_007">OnEnterKeyDown</span><span class="cls_004"> of type </span><span class="cls_007">ICommand</span><span class="cls_004"> in a class named </span><span class="cls_007">TextBoxProperties</span><span class="cls_004">, and we pass a</span></div>
<div style="position:absolute;left:5.00px;top:392.25px" class="cls_004"><span class="cls_004">reference of our handling method to the </span><span class="cls_007">PropertyChangedCallback</span><span class="cls_004"> delegate parameter of</span></div>
<div style="position:absolute;left:5.00px;top:410.25px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">PropertyMetadata</span><span class="cls_004"> constructor.</span></div>
<div style="position:absolute;left:5.00px;top:428.25px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">GetOnEnterKeyDown</span><span class="cls_004"> and </span><span class="cls_007">SetOnEnterKeyDown</span><span class="cls_004"> methods represent the normal way to get</span></div>
<div style="position:absolute;left:5.00px;top:446.25px" class="cls_004"><span class="cls_004">and set Attached Property values. In the unfortunately named </span><span class="cls_007">OnOnEnterKeyDownChanged</span></div>
<div style="position:absolute;left:5.00px;top:464.25px" class="cls_004"><span class="cls_004">method, which will be called when the property value changes, we look at the </span><span class="cls_007">NewValue</span><span class="cls_004"> and</span></div>
<div style="position:absolute;left:5.00px;top:482.25px" class="cls_007"><span class="cls_007">OldValue</span><span class="cls_004"> values of the </span><span class="cls_007">DependencyPropertyChangedEventArgs</span><span class="cls_004"> input parameter in order to</span></div>
<div style="position:absolute;left:5.00px;top:500.25px" class="cls_004"><span class="cls_004">decide whether we need to attach or detach the event handler to the '</span><span class="cls_007">PreviewKeyDown</span><span class="cls_004"> event</span></div>
<div style="position:absolute;left:5.00px;top:518.25px" class="cls_004"><span class="cls_004">of the relevant </span><span class="cls_007">TextBox</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:536.25px" class="cls_004"><span class="cls_004">If the </span><span class="cls_007">OldValue</span><span class="cls_004"> value is null and the </span><span class="cls_007">NewValue</span><span class="cls_004"> value is not null, it means that there was no</span></div>
<div style="position:absolute;left:5.00px;top:554.25px" class="cls_004"><span class="cls_004">previous value, and so the property is being set for the first time. In this case, we want to</span></div>
<div style="position:absolute;left:5.00px;top:572.25px" class="cls_004"><span class="cls_004">attach the event handler. Conversely, when the </span><span class="cls_007">OldValue</span><span class="cls_004"> value is not null and the </span><span class="cls_007">NewValue</span></div>
<div style="position:absolute;left:5.00px;top:590.25px" class="cls_004"><span class="cls_004">value is null, it means that there previously was a value, which has been removed, so we</span></div>
<div style="position:absolute;left:5.00px;top:608.25px" class="cls_004"><span class="cls_004">should detach the event handler.</span></div>
<div style="position:absolute;left:5.00px;top:626.25px" class="cls_004"><span class="cls_004">Finally, the </span><span class="cls_007">TextBox_OnEnterKeyDown</span><span class="cls_004"> event handling method first detects whether either the</span></div>
<div style="position:absolute;left:5.00px;top:644.25px" class="cls_012"><span class="cls_012">Enter</span><span class="cls_006"> </span><span class="cls_004">key or the </span><span class="cls_012">Return</span><span class="cls_006"> </span><span class="cls_004">key were pressed. If one was pressed, the data bound </span><span class="cls_007">ICommand</span></div>
<div style="position:absolute;left:5.00px;top:663.00px" class="cls_004"><span class="cls_004">instance is checked for </span><span class="cls_007">null</span><span class="cls_004"> and if the command can execute, it is then executed.</span></div>
<div style="position:absolute;left:5.00px;top:681.00px" class="cls_004"><span class="cls_004">Therefore, we have effectively wrapped a </span><span class="cls_007">PreviewKeyDown</span><span class="cls_004"> event in an Attached Property</span></div>
<div style="position:absolute;left:5.00px;top:699.00px" class="cls_004"><span class="cls_004">and can now execute any command that has been data bound to it when the user presses</span></div>
<div style="position:absolute;left:5.00px;top:717.00px" class="cls_012"><span class="cls_012">Enter</span><span class="cls_006"> </span><span class="cls_004">on their keyboard.</span></div>
<div style="position:absolute;left:5.00px;top:735.75px" class="cls_004"><span class="cls_004">In order to use this Attached Property, we must first add an XML namespace prefix for our</span></div>
<div style="position:absolute;left:5.00px;top:753.75px" class="cls_007"><span class="cls_007">Attached</span><span class="cls_004"> folder in the XAML file of the View that this functionality is required in. Note that</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:25664px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background034.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">TextBoxProperties</span><span class="cls_004"> class will be declared in the </span><span class="cls_007">Attached</span><span class="cls_004"> folder of the Views project</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">and so, its namespace will be as follows:</span></div>
<div style="position:absolute;left:52.98px;top:45.00px" class="cls_007"><span class="cls_007">xmlns:Attached="clr-</span></div>
<div style="position:absolute;left:52.98px;top:58.50px" class="cls_007"><span class="cls_007">namespace:CompanyName.ApplicationName.Views.Attached;</span></div>
<div style="position:absolute;left:67.97px;top:72.00px" class="cls_007"><span class="cls_007">assembly=CompanyName.ApplicationName.Views"</span></div>
<div style="position:absolute;left:5.00px;top:92.25px" class="cls_004"><span class="cls_004">Microsoft's convention for naming these prefixes is for the first character to be a lowercase</span></div>
<div style="position:absolute;left:5.00px;top:110.25px" class="cls_004"><span class="cls_004">letter, but it has always made more sense to me to simply use the last segment of the</span></div>
<div style="position:absolute;left:5.00px;top:128.25px" class="cls_004"><span class="cls_004">declared namespace, which will start with a capital letter. Once you have defined the prefix,</span></div>
<div style="position:absolute;left:5.00px;top:146.25px" class="cls_004"><span class="cls_004">you can use the Attached Property, as shown in the following example:</span></div>
<div style="position:absolute;left:52.98px;top:169.50px" class="cls_007"><span class="cls_007"><TextBox Attached:TextBoxProperties.OnEnterKeyDown="{Binding</span></div>
<div style="position:absolute;left:52.98px;top:183.00px" class="cls_007"><span class="cls_007">Command}" /></span></div>
<div style="position:absolute;left:5.00px;top:203.25px" class="cls_004"><span class="cls_004">Any UI events that we might need to handle in our applications can be encapsulated in</span></div>
<div style="position:absolute;left:5.00px;top:221.25px" class="cls_004"><span class="cls_004">Attached Properties in this same way. At first, this might seem to be a complicated way to</span></div>
<div style="position:absolute;left:5.00px;top:239.25px" class="cls_004"><span class="cls_004">handle events, compared with having a simple handler in a code behind file, but once we</span></div>
<div style="position:absolute;left:5.00px;top:257.25px" class="cls_004"><span class="cls_004">have a collection of these properties declared, we will find ourselves having to create fewer</span></div>
<div style="position:absolute;left:5.00px;top:275.25px" class="cls_004"><span class="cls_004">and fewer new ones. Think of them as simply being a reusable way of converting events</span></div>
<div style="position:absolute;left:5.00px;top:293.25px" class="cls_004"><span class="cls_004">into properties.</span></div>
<div style="position:absolute;left:5.00px;top:310.51px" class="cls_011"><span class="cls_011">Making use of delegates</span></div>
<div style="position:absolute;left:5.00px;top:340.50px" class="cls_004"><span class="cls_004">Delegates are very similar to events and, in fact, events can be thought of as a particular</span></div>
<div style="position:absolute;left:5.00px;top:358.50px" class="cls_004"><span class="cls_004">kind of delegate. They are a very simple tool to use to pass a signal or message from one</span></div>
<div style="position:absolute;left:5.00px;top:376.50px" class="cls_004"><span class="cls_004">place to another in the program. Unlike when creating custom events, we are not forced to</span></div>
<div style="position:absolute;left:5.00px;top:394.50px" class="cls_004"><span class="cls_004">use particular input parameters, for example, some form of the </span><span class="cls_007">EventArgs</span><span class="cls_004"> class. We are</span></div>
<div style="position:absolute;left:5.00px;top:412.50px" class="cls_004"><span class="cls_004">totally unconstrained when creating custom delegates and are able to define our own</span></div>
<div style="position:absolute;left:5.00px;top:430.50px" class="cls_004"><span class="cls_004">method signatures, including both input and output parameter types.</span></div>
<div style="position:absolute;left:5.00px;top:448.50px" class="cls_004"><span class="cls_004">As most of you will already be familiar with events and event handling, you'll already</span></div>
<div style="position:absolute;left:5.00px;top:466.50px" class="cls_004"><span class="cls_004">inadvertently know how to use delegates too. Let's look at a simple example. Imagine that</span></div>
<div style="position:absolute;left:5.00px;top:484.50px" class="cls_004"><span class="cls_004">we have a parent View Model that spawns child View Models and that one of these child</span></div>
<div style="position:absolute;left:5.00px;top:502.50px" class="cls_004"><span class="cls_004">View Models is paired with a View that enables administrative users to select security</span></div>
<div style="position:absolute;left:5.00px;top:520.50px" class="cls_004"><span class="cls_004">permissions. Now, let's imagine that the parent View that relates to the parent View Model</span></div>
<div style="position:absolute;left:5.00px;top:538.50px" class="cls_004"><span class="cls_004">has a menu that needs to be updated depending on the user's selection in the child View.</span></div>
<div style="position:absolute;left:5.00px;top:556.50px" class="cls_004"><span class="cls_004">How do we notify the parent View Model upon selection?</span></div>
<div style="position:absolute;left:5.00px;top:574.50px" class="cls_004"><span class="cls_004">This is where delegates save the day. Keeping this example simple initially, let's say that we</span></div>
<div style="position:absolute;left:5.00px;top:592.50px" class="cls_004"><span class="cls_004">just need to notify the parent View Model that a particular change has been made so that it</span></div>
<div style="position:absolute;left:5.00px;top:610.50px" class="cls_004"><span class="cls_004">can refresh the current user's security permissions from a database. In this case, we only</span></div>
<div style="position:absolute;left:5.00px;top:628.50px" class="cls_004"><span class="cls_004">need to pass a signal, so we can create a delegate with no input or output parameters. We</span></div>
<div style="position:absolute;left:5.00px;top:646.50px" class="cls_004"><span class="cls_004">can declare it in the View Model that will be sending the signal, in this case, the child View</span></div>
<div style="position:absolute;left:5.00px;top:664.50px" class="cls_004"><span class="cls_004">Model.</span></div>
<div style="position:absolute;left:52.98px;top:687.75px" class="cls_007"><span class="cls_007">public delegate void Signal();</span></div>
<div style="position:absolute;left:5.00px;top:708.00px" class="cls_004"><span class="cls_004">Note that we define it in the same way that we define an abstract method, except that the</span></div>
<div style="position:absolute;left:5.00px;top:726.00px" class="cls_007"><span class="cls_007">abstract</span><span class="cls_004"> keyword is replaced with the </span><span class="cls_007">delegate</span><span class="cls_004"> keyword after the access modifier. In</span></div>
<div style="position:absolute;left:5.00px;top:744.00px" class="cls_004"><span class="cls_004">short, a delegate defines a type that references a method with a particular signature. Now</span></div>
<div style="position:absolute;left:5.00px;top:762.00px" class="cls_004"><span class="cls_004">that we have defined our signaling delegate, we need to create a way for elements outside</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:26466px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background035.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">the View Model to use it. For this, we can simply create a property of the type of our new</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">delegate </span><span class="cls_006">in the same View Model</span><span class="cls_004">:</span></div>
<div style="position:absolute;left:52.98px;top:45.75px" class="cls_007"><span class="cls_007">public Signal OnSecurityPermissionChanged { get; set; }</span></div>
<div style="position:absolute;left:5.00px;top:66.00px" class="cls_004"><span class="cls_004">As we don't need any property change notifications for this property, we can save ourselves</span></div>
<div style="position:absolute;left:5.00px;top:84.00px" class="cls_004"><span class="cls_004">some typing and take advantage of the .NET Auto-Implemented Property syntax. Bear in</span></div>
<div style="position:absolute;left:5.00px;top:102.00px" class="cls_004"><span class="cls_004">mind that delegates work in a multicast way like events, meaning that we can attach more</span></div>
<div style="position:absolute;left:5.00px;top:120.00px" class="cls_004"><span class="cls_004">than one handler to each one. In order to do this, we need to use the </span><span class="cls_007">+=</span><span class="cls_004"> operator to add</span></div>
<div style="position:absolute;left:5.00px;top:138.00px" class="cls_004"><span class="cls_004">handlers for the delegate, and in this example, we would want to do that in the parent View</span></div>
<div style="position:absolute;left:5.00px;top:156.00px" class="cls_004"><span class="cls_004">Model when the child View is instantiated:</span></div>
<div style="position:absolute;left:52.98px;top:179.25px" class="cls_007"><span class="cls_007">ChildViewModel viewModel = new ChildViewModel();</span></div>
<div style="position:absolute;left:52.98px;top:192.75px" class="cls_007"><span class="cls_007">viewModel.OnSecurityPermissionChanged +=</span></div>
<div style="position:absolute;left:52.98px;top:206.25px" class="cls_007"><span class="cls_007">RefreshSecurityPermissions;</span></div>
<div style="position:absolute;left:5.00px;top:226.50px" class="cls_004"><span class="cls_004">Here, we have assigned the </span><span class="cls_007">RefreshSecurityPermissions</span><span class="cls_004"> method in the parent View</span></div>
<div style="position:absolute;left:5.00px;top:244.50px" class="cls_004"><span class="cls_004">Model to be the handler for this delegate. Note that we omit the parenthesis and the input</span></div>
<div style="position:absolute;left:5.00px;top:262.50px" class="cls_004"><span class="cls_004">parameters if there were any when attaching the handler. Now, you may be wondering,</span></div>
<div style="position:absolute;left:5.00px;top:280.50px" class="cls_004"><span class="cls_004">"What does the method signature of this handler look like?", but you already have the</span></div>
<div style="position:absolute;left:5.00px;top:298.50px" class="cls_004"><span class="cls_004">answer to this. If you remember, we declared the delegate with the signature of the method</span></div>
<div style="position:absolute;left:5.00px;top:316.50px" class="cls_004"><span class="cls_004">that we want to handle it. Therefore, any method that shares this signature can be a</span></div>
<div style="position:absolute;left:5.00px;top:334.50px" class="cls_004"><span class="cls_004">handler for this type of delegate:</span></div>
<div style="position:absolute;left:52.98px;top:357.75px" class="cls_007"><span class="cls_007">private void RefreshSecurityPermissions()</span></div>
<div style="position:absolute;left:52.98px;top:371.25px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:384.75px" class="cls_007"><span class="cls_007">// Refresh user's security permissions when alerted by the signal</span></div>
<div style="position:absolute;left:52.98px;top:398.25px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:431.25px" class="cls_004"><span class="cls_004">Note that the name used is irrelevant and all that matters when matching the delegate</span></div>
<div style="position:absolute;left:5.00px;top:449.25px" class="cls_004"><span class="cls_004">signature are the input and output parameters. So, we now have our delegate declared and</span></div>
<div style="position:absolute;left:5.00px;top:467.25px" class="cls_004"><span class="cls_004">hooked up to a handler in the parent View Model, but it's still not going to do anything</span></div>
<div style="position:absolute;left:5.00px;top:485.25px" class="cls_004"><span class="cls_004">because we haven't actually called it yet. In our example, it's the child View Model that is</span></div>
<div style="position:absolute;left:5.00px;top:503.25px" class="cls_004"><span class="cls_004">going to call the delegate because that's the object that needs to send out the information,</span></div>
<div style="position:absolute;left:5.00px;top:521.25px" class="cls_004"><span class="cls_004">or signal in this case.</span></div>
<div style="position:absolute;left:5.00px;top:539.25px" class="cls_004"><span class="cls_004">When calling delegates, we must always remember to check for </span><span class="cls_007">null</span><span class="cls_004"> before trying to use</span></div>
<div style="position:absolute;left:5.00px;top:557.25px" class="cls_004"><span class="cls_004">them because there may be no handlers attached. In our example, we'd call our </span><span class="cls_007">Signal</span></div>
<div style="position:absolute;left:5.00px;top:575.25px" class="cls_004"><span class="cls_004">delegate via the </span><span class="cls_007">OnSecurityPermissionChanged</span><span class="cls_004"> property at the point that we need to send</span></div>
<div style="position:absolute;left:5.00px;top:593.25px" class="cls_004"><span class="cls_004">the signal from the child View Model, let's say in reaction to a user changing their own</span></div>
<div style="position:absolute;left:5.00px;top:611.25px" class="cls_004"><span class="cls_004">security permissions:</span></div>
<div style="position:absolute;left:52.98px;top:634.50px" class="cls_007"><span class="cls_007">if (OnSecurityPermissionChanged != null)</span></div>
<div style="position:absolute;left:52.98px;top:648.00px" class="cls_007"><span class="cls_007">OnSecurityPermissionChanged();</span></div>
<div style="position:absolute;left:5.00px;top:668.25px" class="cls_004"><span class="cls_004">Alternatively, we could do so using the more concise null conditional operator in C# version</span></div>
<div style="position:absolute;left:5.00px;top:686.25px" class="cls_004"><span class="cls_004">6.0, which calls the delegate's </span><span class="cls_007">Invoke</span><span class="cls_004"> method if it is not null:</span></div>
<div style="position:absolute;left:52.98px;top:709.50px" class="cls_007"><span class="cls_007">OnSecurityPermissionChanged?.Invoke();</span></div>
<div style="position:absolute;left:5.00px;top:729.75px" class="cls_004"><span class="cls_004">Note that we do need to include the parenthesis when calling the delegate in the first</span></div>
<div style="position:absolute;left:5.00px;top:747.75px" class="cls_004"><span class="cls_004">example even though </span><span class="cls_007">OnSecurityPermissionChanged</span><span class="cls_004"> is a property. This is because the</span></div>
<div style="position:absolute;left:5.00px;top:765.75px" class="cls_004"><span class="cls_004">delegate type of the property relates to a method and it is that method that we are calling.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:27268px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background036.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">Please bear in mind that the first of these methods is not thread safe, so if thread safety is</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">important for your application, then you will need to use the latter way.</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">We now have the complete picture, but while it is common to have a signal-sending</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">delegate such as this, it is not overly useful because it only passes a signal with no other</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">information. In many real-world scenarios, we would typically want to have some sort of</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">input parameter so that we could pass some information, rather than just a signal.</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">For example, if we wanted to be notified with details each time a user selected a different</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">item from a collection control in the UI, we could add a </span><span class="cls_007">CurrentItem</span><span class="cls_004"> property into a generic</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_007"><span class="cls_007">BaseCollection</span><span class="cls_004"> class in our application and data bind it to the data bound collection</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">control's </span><span class="cls_007">SelectedItem</span><span class="cls_004"> property. This </span><span class="cls_007">CurrentItem</span><span class="cls_004"> property would then be called by the</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">WPF Framework each time a user makes a new selection, and so we can call our new</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">delegate from its property setter:</span></div>
<div style="position:absolute;left:52.98px;top:225.00px" class="cls_007"><span class="cls_007">protected T currentItem;</span></div>
<div style="position:absolute;left:52.98px;top:252.00px" class="cls_007"><span class="cls_007">public virtual CurrentItemChange CurrentItemChanged { get; set; }</span></div>
<div style="position:absolute;left:52.98px;top:279.00px" class="cls_007"><span class="cls_007">public virtual T CurrentItem</span></div>
<div style="position:absolute;left:52.98px;top:292.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:306.00px" class="cls_007"><span class="cls_007">get { return currentItem; }</span></div>
<div style="position:absolute;left:67.97px;top:319.50px" class="cls_007"><span class="cls_007">set</span></div>
<div style="position:absolute;left:67.97px;top:333.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:346.50px" class="cls_007"><span class="cls_007">T oldCurrentItem = currentItem;</span></div>
<div style="position:absolute;left:82.97px;top:360.00px" class="cls_007"><span class="cls_007">currentItem = value;</span></div>
<div style="position:absolute;left:82.97px;top:373.50px" class="cls_007"><span class="cls_007">CurrentItemChanged?.Invoke(oldCurrentItem, currentItem);</span></div>
<div style="position:absolute;left:82.97px;top:387.00px" class="cls_007"><span class="cls_007">NotifyPropertyChanged();</span></div>
<div style="position:absolute;left:67.97px;top:400.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:414.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:434.25px" class="cls_004"><span class="cls_004">Delegates can be used to communicate between any related classes as long as they have</span></div>
<div style="position:absolute;left:5.00px;top:452.25px" class="cls_004"><span class="cls_004">access to the class that exposes the delegate so that they can attach a handler. They are</span></div>
<div style="position:absolute;left:5.00px;top:470.25px" class="cls_004"><span class="cls_004">commonly used to send information between child Views or View Models and their parents,</span></div>
<div style="position:absolute;left:5.00px;top:488.25px" class="cls_004"><span class="cls_004">or even between Views and View Models, but they can also be used to pass data between</span></div>
<div style="position:absolute;left:5.00px;top:506.25px" class="cls_004"><span class="cls_004">any two connected parts of the application.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:28070px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background037.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_008"><span class="cls_008">Structuring the application code base</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">Now that we have a better understanding of the MVVM pattern, let's look at how we might</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">implement it in a WPF application. What should the folder structure of our application be</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">like? Clearly, we'll need somewhere to put our Models, Views, and View Models; however,</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">how we arrange them will somewhat depend on the overall size of our application.</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">As we have heard, very small projects do not really suit MVVM because implementing it can</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">involve a lot of preparation and often, the benefits do not apply. For small WPF applications,</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">we would typically have just one project in our WPF application. In these cases, our classes</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">would be separated into different folders within the single project.</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">With larger scale applications, we arrange our classes in the same basic structure, but as</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">there are more classes and more chance that we want to reuse some of this code, it</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">makes sense to use separate projects instead of folders. Either way, our classes should</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">end up with the same CLR namespaces, as they tend to follow the structure of the</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">application, regardless of whether those classes were separated using folders or projects.</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">While the CLR namespace in our startup project might be something along the lines of</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_007"><span class="cls_007">CompanyName.ApplicationName</span><span class="cls_004">, the namespace of the classes in the Models component</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">would be, or start with, </span><span class="cls_007">CompanyName.ApplicationName.Models</span><span class="cls_004">. For the purpose of the</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_004"><span class="cls_004">remainder of this book, we will assume that we are dealing with a large-scale WPF</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_004"><span class="cls_004">application and using projects for the separation of our classes.</span></div>
<div style="position:absolute;left:5.00px;top:363.75px" class="cls_004"><span class="cls_004">There is nothing in the MVVM pattern that dictates what structure our code base should</span></div>
<div style="position:absolute;left:5.00px;top:381.75px" class="cls_004"><span class="cls_004">have, although there are clues. We will clearly need </span><span class="cls_007">Views</span><span class="cls_004"> and </span><span class="cls_007">ViewModels</span><span class="cls_004"> projects, but the</span></div>
<div style="position:absolute;left:5.00px;top:399.75px" class="cls_007"><span class="cls_007">Models</span><span class="cls_004"> project is less clearly defined. There are several elements within the Models</span></div>
<div style="position:absolute;left:5.00px;top:417.75px" class="cls_004"><span class="cls_004">component of MVVM, but we don't necessarily want to group them all into a single project</span></div>
<div style="position:absolute;left:5.00px;top:435.75px" class="cls_004"><span class="cls_004">in our code base. There are other projects that will be required too.</span></div>
<div style="position:absolute;left:5.00px;top:453.75px" class="cls_004"><span class="cls_004">Let's visualize some possible structures so that we can get started with building our</span></div>
<div style="position:absolute;left:5.00px;top:471.75px" class="cls_004"><span class="cls_004">application.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:28872px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background038.jpg" width=612 height=792></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:29674px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background039.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:441.75px" class="cls_004"><span class="cls_004">These examples offer an insight into what the project structure of an MVVM-based WPF</span></div>
<div style="position:absolute;left:5.00px;top:459.75px" class="cls_004"><span class="cls_004">application might look like. However, nothing is set in stone and we are free to rename and</span></div>
<div style="position:absolute;left:5.00px;top:477.75px" class="cls_004"><span class="cls_004">to reorganize our application projects as we see fit. The important thing is how the</span></div>
<div style="position:absolute;left:5.00px;top:495.75px" class="cls_004"><span class="cls_004">components are connected together rather than the arrangement of the application files.</span></div>
<div style="position:absolute;left:5.00px;top:513.75px" class="cls_004"><span class="cls_004">After we have developed a number of WPF applications, we get a feel for which project</span></div>
<div style="position:absolute;left:5.00px;top:531.75px" class="cls_004"><span class="cls_004">names and which structure we prefer, so I'd suggest trying a few variations and seeing</span></div>
<div style="position:absolute;left:5.00px;top:549.75px" class="cls_004"><span class="cls_004">which you feel more comfortable working with. Of course, some of us may not have the</span></div>
<div style="position:absolute;left:5.00px;top:567.75px" class="cls_004"><span class="cls_004">luxury of being able to create or alter the structure of the application that we work on. Let's</span></div>
<div style="position:absolute;left:5.00px;top:585.75px" class="cls_004"><span class="cls_004">first focus on the projects common to both example structures.</span></div>
<div style="position:absolute;left:5.00px;top:603.75px" class="cls_004"><span class="cls_004">We see that the </span><span class="cls_007">Images</span><span class="cls_004"> and </span><span class="cls_007">Resources</span><span class="cls_004"> folders reside in the startup project. While this is</span></div>
<div style="position:absolute;left:5.00px;top:621.75px" class="cls_004"><span class="cls_004">customary, they </span><span class="cls_006">can</span><span class="cls_004"> technically reside in any project or even in their own project. However,</span></div>
<div style="position:absolute;left:5.00px;top:640.50px" class="cls_004"><span class="cls_004">I prefer to keep them in this project because it provides a marginal performance benefit.</span></div>
<div style="position:absolute;left:5.00px;top:658.50px" class="cls_004"><span class="cls_004">Typically, when using MVVM, the only other files in the startup project will be the</span></div>
<div style="position:absolute;left:5.00px;top:676.50px" class="cls_007"><span class="cls_007">MainWindow.xaml</span><span class="cls_004">, </span><span class="cls_007">App.xaml</span><span class="cls_004"> (and their constituent code behind files), and </span><span class="cls_007">app.config</span><span class="cls_004"> files.</span></div>
<div style="position:absolute;left:5.00px;top:694.50px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">Images</span><span class="cls_004"> folder contains the images and icons that are displayed in the UI controls,</span></div>
<div style="position:absolute;left:5.00px;top:712.50px" class="cls_004"><span class="cls_004">whereas the </span><span class="cls_007">Resources</span><span class="cls_004"> folder normally contains any resource files, such as XML schemas</span></div>
<div style="position:absolute;left:5.00px;top:730.50px" class="cls_004"><span class="cls_004">or text or data files that are used by the application.</span></div>
<div style="position:absolute;left:5.00px;top:748.50px" class="cls_004"><span class="cls_004">The next project is named </span><span class="cls_007">Converters</span><span class="cls_004"> and is fairly self-explanatory. It only contains classes</span></div>
<div style="position:absolute;left:5.00px;top:766.50px" class="cls_004"><span class="cls_004">that have implemented the </span><span class="cls_007">IValueConverter</span><span class="cls_004"> interface and are used for converting data</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:30476px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background040.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">bound values in the Views. These classes are all reusable and the DLL from this project</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">should be kept up to date and shared amongst our other applications.</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">Both examples show an </span><span class="cls_007">Extensions</span><span class="cls_004"> project, but this is entirely optional and not a</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">requirement of the MVVM pattern. I just happen to find Extension methods to be an</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">essential part of .NET development, having built up a large collection of invaluable helper</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">methods. After getting used to being able to call </span><span class="cls_007">Add</span><span class="cls_004"> on an </span><span class="cls_007">IEnumerable</span><span class="cls_004"> instance or</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_007"><span class="cls_007">ToObservableCollection</span><span class="cls_004"> on a query result for example, I now reuse them in every</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">application. We'll see some examples of these in </span><span class="cls_015">Chapter 3 </span><span class="cls_004">, </span><span class="cls_006">Writing Custom Application</span></div>
<div style="position:absolute;left:5.00px;top:148.50px" class="cls_006"><span class="cls_006">Frameworks</span><span class="cls_004">, </span><span class="cls_015">Chapter 8</span><span class="cls_004">, </span><span class="cls_006">Implementing Responsive Data Validation</span><span class="cls_004">, and </span><span class="cls_015">Chapter 9</span><span class="cls_004">,</span></div>
<div style="position:absolute;left:5.00px;top:167.25px" class="cls_006"><span class="cls_006">Completing That Great User Experience</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:186.00px" class="cls_004"><span class="cls_004">The next common project that we can see is a project called </span><span class="cls_007">Managers</span><span class="cls_004">. Others may prefer</span></div>
<div style="position:absolute;left:5.00px;top:204.00px" class="cls_004"><span class="cls_004">to call this </span><span class="cls_007">Engines</span><span class="cls_004">, </span><span class="cls_007">Services</span><span class="cls_004">, or something similar, but that is just a personal preference,</span></div>
<div style="position:absolute;left:5.00px;top:222.00px" class="cls_004"><span class="cls_004">and either way, the content will be the same. In this project, we typically find a number of</span></div>
<div style="position:absolute;left:5.00px;top:240.00px" class="cls_004"><span class="cls_004">classes that together provide a wide variety of functionality to the View Models. For</span></div>
<div style="position:absolute;left:5.00px;top:258.00px" class="cls_004"><span class="cls_004">example, in this project, we might find classes named </span><span class="cls_007">ExportManager</span><span class="cls_004">, </span><span class="cls_007">FeedbackManager</span><span class="cls_004">,</span></div>
<div style="position:absolute;left:5.00px;top:276.00px" class="cls_007"><span class="cls_007">HardDriveManager</span><span class="cls_004">, </span><span class="cls_007">WindowManager</span><span class="cls_004">, and so on.</span></div>
<div style="position:absolute;left:5.00px;top:294.00px" class="cls_004"><span class="cls_004">It is important to have a project like this, where we have one common place to provide all of</span></div>
<div style="position:absolute;left:5.00px;top:312.00px" class="cls_004"><span class="cls_004">the required specialized functionality for our application, rather than having to repeat the</span></div>
<div style="position:absolute;left:5.00px;top:330.00px" class="cls_004"><span class="cls_004">code in each View Model that requires that certain functionality. These classes are totally</span></div>
<div style="position:absolute;left:5.00px;top:348.00px" class="cls_004"><span class="cls_004">reusable between applications and this arrangement also promotes behavioral consistency</span></div>
<div style="position:absolute;left:5.00px;top:366.00px" class="cls_004"><span class="cls_004">throughout the application.</span></div>
<div style="position:absolute;left:5.00px;top:384.00px" class="cls_004"><span class="cls_004">For example, without consolidating all of our functionality in this project, we might be</span></div>
<div style="position:absolute;left:5.00px;top:402.00px" class="cls_004"><span class="cls_004">tempted to copy and paste certain bits of code from one View Model to another. If the code</span></div>
<div style="position:absolute;left:5.00px;top:420.00px" class="cls_004"><span class="cls_004">then requires a change in the future, we may not remember that it has been copied and only</span></div>
<div style="position:absolute;left:5.00px;top:438.00px" class="cls_004"><span class="cls_004">update it in one View Model, thereby breaking the consistency of the application.</span></div>
<div style="position:absolute;left:5.00px;top:456.00px" class="cls_004"><span class="cls_004">Another benefit to utilizing a project like this is that it reduces the number of references that</span></div>
<div style="position:absolute;left:5.00px;top:474.00px" class="cls_004"><span class="cls_004">the other projects need. The </span><span class="cls_007">Managers</span><span class="cls_004"> project will typically require many references to be</span></div>
<div style="position:absolute;left:5.00px;top:492.00px" class="cls_004"><span class="cls_004">added, whereas the View Model and other classes that make use of its functionality will</span></div>
<div style="position:absolute;left:5.00px;top:510.00px" class="cls_004"><span class="cls_004">only need to add a single reference to this project.</span></div>
<div style="position:absolute;left:5.00px;top:528.00px" class="cls_004"><span class="cls_004">Some or all of the functionality from these classes can be exposed through a</span></div>
<div style="position:absolute;left:5.00px;top:546.00px" class="cls_007"><span class="cls_007">BaseViewModel</span><span class="cls_004"> class and can therefore be made available to every View Model. We'll see</span></div>
<div style="position:absolute;left:5.00px;top:564.00px" class="cls_004"><span class="cls_004">more about this in </span><span class="cls_015">Chapter 3</span><span class="cls_004">, </span><span class="cls_006">Writing Custom Application Frameworks</span><span class="cls_004">, but for now, let's</span></div>
<div style="position:absolute;left:5.00px;top:582.75px" class="cls_004"><span class="cls_004">start to look at the differences between the two structures.</span></div>
<div style="position:absolute;left:5.00px;top:600.75px" class="cls_004"><span class="cls_004">In the first structure example, the </span><span class="cls_007">Business</span><span class="cls_004"> folder within the </span><span class="cls_007">Models</span><span class="cls_004"> project simply</span></div>
<div style="position:absolute;left:5.00px;top:618.75px" class="cls_004"><span class="cls_004">represents the business data models of the application. There's no real need to have these</span></div>
<div style="position:absolute;left:5.00px;top:636.75px" class="cls_004"><span class="cls_004">classes in a separate </span><span class="cls_007">Business</span><span class="cls_004"> folder other than the fact that it highlights that they are</span></div>
<div style="position:absolute;left:5.00px;top:654.75px" class="cls_004"><span class="cls_004">connected with the </span><span class="cls_007">ViewModels.Business</span><span class="cls_004"> View Models and the </span><span class="cls_007">Views.Business</span><span class="cls_004"> Views.</span></div>
<div style="position:absolute;left:5.00px;top:672.75px" class="cls_004"><span class="cls_004">Technically, the data model classes in our application should represent our business objects</span></div>
<div style="position:absolute;left:5.00px;top:690.75px" class="cls_004"><span class="cls_004">and not contain any properties that bear no relevance to the business model, such as</span></div>
<div style="position:absolute;left:5.00px;top:708.75px" class="cls_004"><span class="cls_004">properties named </span><span class="cls_007">CurrentItem</span><span class="cls_004"> or </span><span class="cls_007">IsSelected</span><span class="cls_004">. If this were the case and they were defined</span></div>
<div style="position:absolute;left:5.00px;top:726.75px" class="cls_004"><span class="cls_004">in their own project, as shown in the first example, then we could reuse their DLL in our</span></div>
<div style="position:absolute;left:5.00px;top:744.75px" class="cls_004"><span class="cls_004">other business applications. Alternatively, perhaps we already have a DLL representing the</span></div>
<div style="position:absolute;left:5.00px;top:762.75px" class="cls_004"><span class="cls_004">business model from another application that we will be reusing in the next application.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:31278px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background041.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">In either of these cases, we would need to add other folders into the </span><span class="cls_007">ViewModels</span><span class="cls_004"> project in</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">which we would implement an additional View Model class for each business model class to</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">be displayed. This arrangement is shown in the </span><span class="cls_007">ViewModels</span><span class="cls_004">.</span><span class="cls_007">Business</span><span class="cls_004"> folder of the first</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">example and demonstrates the separation of the data model from the Views.</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">In these classes, we would encapsulate each public business model property in a new</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">property that raised change notification and add any further properties required by the UI. It</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">would look similar to the following example, where the </span><span class="cls_007">BaseBusinessViewModel</span><span class="cls_004"> class simply</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">implements the </span><span class="cls_007">INotifyPropertyChanged</span><span class="cls_004"> interface:</span></div>
<div style="position:absolute;left:52.98px;top:153.00px" class="cls_007"><span class="cls_007">using System;</span></div>
<div style="position:absolute;left:52.98px;top:180.00px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.Models.Business</span></div>
<div style="position:absolute;left:52.98px;top:193.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:207.00px" class="cls_007"><span class="cls_007">public class User</span></div>
<div style="position:absolute;left:67.97px;top:220.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:234.00px" class="cls_007"><span class="cls_007">public User(Guid id, string name, int age)</span></div>
<div style="position:absolute;left:82.97px;top:247.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:261.00px" class="cls_007"><span class="cls_007">Id = id;</span></div>
<div style="position:absolute;left:97.96px;top:274.50px" class="cls_007"><span class="cls_007">Name = name;</span></div>
<div style="position:absolute;left:97.96px;top:288.00px" class="cls_007"><span class="cls_007">Age = age;</span></div>
<div style="position:absolute;left:82.97px;top:301.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:328.50px" class="cls_007"><span class="cls_007">public Guid Id { get; set; }</span></div>
<div style="position:absolute;left:82.97px;top:355.50px" class="cls_007"><span class="cls_007">public string Name { get; set; }</span></div>
<div style="position:absolute;left:82.97px;top:382.50px" class="cls_007"><span class="cls_007">public int Age { get; set; }</span></div>
<div style="position:absolute;left:67.97px;top:396.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:409.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:436.50px" class="cls_007"><span class="cls_007">using System;</span></div>
<div style="position:absolute;left:52.98px;top:450.00px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.Models.Business;</span></div>
<div style="position:absolute;left:52.98px;top:477.00px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.ViewModels.Business</span></div>
<div style="position:absolute;left:52.98px;top:490.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:504.00px" class="cls_007"><span class="cls_007">public class UserViewModel : BaseBusinessViewModel</span></div>
<div style="position:absolute;left:67.97px;top:517.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:531.00px" class="cls_007"><span class="cls_007">private User model;</span></div>
<div style="position:absolute;left:82.97px;top:544.50px" class="cls_007"><span class="cls_007">private bool isSelected = false;</span></div>
<div style="position:absolute;left:82.97px;top:571.50px" class="cls_007"><span class="cls_007">public UserViewModel(User model)</span></div>
<div style="position:absolute;left:82.97px;top:585.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:598.50px" class="cls_007"><span class="cls_007">Model = model;</span></div>
<div style="position:absolute;left:82.97px;top:612.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:639.00px" class="cls_007"><span class="cls_007">public User Model</span></div>
<div style="position:absolute;left:82.97px;top:652.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:666.00px" class="cls_007"><span class="cls_007">get { return model; }</span></div>
<div style="position:absolute;left:97.96px;top:679.50px" class="cls_007"><span class="cls_007">set { model = value; NotifyPropertyChanged(); }</span></div>
<div style="position:absolute;left:82.97px;top:693.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:720.00px" class="cls_007"><span class="cls_007">public Guid Id</span></div>
<div style="position:absolute;left:82.97px;top:733.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:747.00px" class="cls_007"><span class="cls_007">get { return Model.Id; }</span></div>
<div style="position:absolute;left:97.96px;top:760.50px" class="cls_007"><span class="cls_007">set { Model.Id = value; NotifyPropertyChanged(); }</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:32080px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background042.jpg" width=612 height=792></div>
<div style="position:absolute;left:82.97px;top:3.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:30.00px" class="cls_007"><span class="cls_007">public string Name</span></div>
<div style="position:absolute;left:82.97px;top:43.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:57.00px" class="cls_007"><span class="cls_007">get { return Model.Name; }</span></div>
<div style="position:absolute;left:97.96px;top:70.50px" class="cls_007"><span class="cls_007">set { Model.Name = value; NotifyPropertyChanged(); }</span></div>
<div style="position:absolute;left:82.97px;top:84.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:111.00px" class="cls_007"><span class="cls_007">public int Age</span></div>
<div style="position:absolute;left:82.97px;top:124.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:138.00px" class="cls_007"><span class="cls_007">get { return Model.Age; }</span></div>
<div style="position:absolute;left:97.96px;top:151.50px" class="cls_007"><span class="cls_007">set { Model.Age = value; NotifyPropertyChanged(); }</span></div>
<div style="position:absolute;left:82.97px;top:165.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:192.00px" class="cls_007"><span class="cls_007">public bool IsSelected</span></div>
<div style="position:absolute;left:82.97px;top:205.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:219.00px" class="cls_007"><span class="cls_007">get { return isSelected; }</span></div>
<div style="position:absolute;left:97.96px;top:232.50px" class="cls_007"><span class="cls_007">set { isSelected = value; NotifyPropertyChanged(); }</span></div>
<div style="position:absolute;left:82.97px;top:246.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:259.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:273.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:293.25px" class="cls_004"><span class="cls_004">When implementing this pattern, after each data object was loaded from the data source, it</span></div>
<div style="position:absolute;left:5.00px;top:311.25px" class="cls_004"><span class="cls_004">would need to be wrapped in one of these View Model classes before being displayed in</span></div>
<div style="position:absolute;left:5.00px;top:329.25px" class="cls_004"><span class="cls_004">the UI:</span></div>
<div style="position:absolute;left:52.98px;top:352.50px" class="cls_007"><span class="cls_007">User user = new User(Guid.NewGuid(), "John Smith", 25);</span></div>
<div style="position:absolute;left:52.98px;top:366.00px" class="cls_007"><span class="cls_007">UserViewModel userViewModel = new UserViewModel(user);</span></div>
<div style="position:absolute;left:5.00px;top:386.25px" class="cls_004"><span class="cls_004">Following the pattern in the first example structure through to the </span><span class="cls_007">Views</span><span class="cls_004"> project, we see that</span></div>
<div style="position:absolute;left:5.00px;top:404.25px" class="cls_004"><span class="cls_004">it also contains a </span><span class="cls_007">Business</span><span class="cls_004"> folder. Typically, we could find a small, individual object-sized</span></div>
<div style="position:absolute;left:5.00px;top:422.25px" class="cls_004"><span class="cls_004">View there for each of these business model-related View Models. However, in the vast</span></div>
<div style="position:absolute;left:5.00px;top:440.25px" class="cls_004"><span class="cls_004">majority of applications, this additional level of separation between the business model and</span></div>
<div style="position:absolute;left:5.00px;top:458.25px" class="cls_004"><span class="cls_004">the UI is simply unrequired. Also, following this pattern adds a small overhead to all</span></div>
<div style="position:absolute;left:5.00px;top:476.25px" class="cls_004"><span class="cls_004">implementation and data access times.</span></div>
<div style="position:absolute;left:5.00px;top:494.25px" class="cls_004"><span class="cls_004">For some, a viable alternative would be to simply add the properties and property change</span></div>
<div style="position:absolute;left:5.00px;top:512.25px" class="cls_004"><span class="cls_004">notification required by the UI straight into the data model classes. If we don't need this</span></div>
<div style="position:absolute;left:5.00px;top:530.25px" class="cls_004"><span class="cls_004">separation, then there is little point in writing all of the extra code. I am a great fan of Agile</span></div>
<div style="position:absolute;left:5.00px;top:548.25px" class="cls_004"><span class="cls_004">practices and one of the twelve principles from the </span><span class="cls_006">Manifesto for Agile Software</span></div>
<div style="position:absolute;left:5.00px;top:567.00px" class="cls_006"><span class="cls_006">Development</span><span class="cls_004"> summarizes this point perfectly:</span></div>
<div style="position:absolute;left:53.35px;top:585.75px" class="cls_006"><span class="cls_006">"Simplicity--the art of maximizing the amount of work not done--is essential"</span></div>
<div style="position:absolute;left:5.00px;top:604.50px" class="cls_004"><span class="cls_004">This simpler, alternative implementation is shown in the </span><span class="cls_007">DataModels</span><span class="cls_004"> project of the second</span></div>
<div style="position:absolute;left:5.00px;top:622.50px" class="cls_004"><span class="cls_004">example, where the business model classes are combined with the UI-related properties</span></div>
<div style="position:absolute;left:5.00px;top:640.50px" class="cls_004"><span class="cls_004">along with the business rules or validation logic.</span></div>
<div style="position:absolute;left:5.00px;top:658.50px" class="cls_004"><span class="cls_004">In other types of applications, you may find a separate validation layer that sits between the</span></div>
<div style="position:absolute;left:5.00px;top:676.50px" class="cls_004"><span class="cls_004">DAL and the code behind the UI layer. As we'll see in </span><span class="cls_015">Chapter 8</span><span class="cls_004">, </span><span class="cls_006">Implementing Responsive</span></div>
<div style="position:absolute;left:5.00px;top:695.25px" class="cls_006"><span class="cls_006">Data Validation</span><span class="cls_004">, with WPF, we can build validation right into the business classes, along</span></div>
<div style="position:absolute;left:5.00px;top:714.00px" class="cls_004"><span class="cls_004">with the properties that they are validating.</span></div>
<div style="position:absolute;left:5.00px;top:732.00px" class="cls_004"><span class="cls_004">This </span><span class="cls_007">DataModels</span><span class="cls_004"> project contains a number of sub-folders, grouping similar types of classes</span></div>
<div style="position:absolute;left:5.00px;top:750.00px" class="cls_004"><span class="cls_004">together. The </span><span class="cls_007">Collections</span><span class="cls_004"> folder typically contains an extension of the</span></div>
<div style="position:absolute;left:5.00px;top:768.00px" class="cls_007"><span class="cls_007">ObservableCollection<T></span><span class="cls_004"> class for each data model class in the application. The </span><span class="cls_007">Enums</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:32882px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background043.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">folder is also often well used in most WPF applications, as enumerations are great to use</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">when data bound to either radio buttons or checkboxes.</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">The interfaces found in the </span><span class="cls_007">Interfaces</span><span class="cls_004"> folder are essential to enable the functionality of the</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">base classes, as we'll see in </span><span class="cls_015">Chapter 3</span><span class="cls_004">, </span><span class="cls_006">Writing Custom Application Frameworks</span><span class="cls_004">. If we're</span></div>
<div style="position:absolute;left:5.00px;top:76.50px" class="cls_004"><span class="cls_004">likely to use a large number of delegates in our application, then it also makes sense to</span></div>
<div style="position:absolute;left:5.00px;top:94.50px" class="cls_004"><span class="cls_004">organize them into a separate </span><span class="cls_007">Delegates</span><span class="cls_004"> folder as well. Otherwise, if a delegate is strongly</span></div>
<div style="position:absolute;left:5.00px;top:112.50px" class="cls_004"><span class="cls_004">tied to a particular class, they can just be declared locally in the classes that will be raising</span></div>
<div style="position:absolute;left:5.00px;top:130.50px" class="cls_004"><span class="cls_004">them.</span></div>
<div style="position:absolute;left:5.00px;top:148.50px" class="cls_004"><span class="cls_004">One other alternative would be to have a single class in the </span><span class="cls_007">Models</span><span class="cls_004"> project that</span></div>
<div style="position:absolute;left:5.00px;top:166.50px" class="cls_004"><span class="cls_004">encapsulates all of the application delegates, although this would require prefixing the name</span></div>
<div style="position:absolute;left:5.00px;top:184.50px" class="cls_004"><span class="cls_004">of this class to the delegate names when using them, for example,</span></div>
<div style="position:absolute;left:5.00px;top:202.50px" class="cls_007"><span class="cls_007">Delegates.CloseRequest</span><span class="cls_004">. Declaring each delegate in the class that uses them enables us</span></div>
<div style="position:absolute;left:5.00px;top:220.50px" class="cls_004"><span class="cls_004">to reference them directly, for example, </span><span class="cls_007">CloseRequest</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:238.50px" class="cls_004"><span class="cls_004">The data model classes in this project could be thought of as View Models too, although</span></div>
<div style="position:absolute;left:5.00px;top:256.50px" class="cls_004"><span class="cls_004">View Models that only serve the display of individual objects, as opposed to those that</span></div>
<div style="position:absolute;left:5.00px;top:274.50px" class="cls_004"><span class="cls_004">serve the main application Views. They would have a base class that implements the</span></div>
<div style="position:absolute;left:5.00px;top:292.50px" class="cls_007"><span class="cls_007">INotifyPropertyChanged</span><span class="cls_004"> interface like the main View Models, but then it would also</span></div>
<div style="position:absolute;left:5.00px;top:310.50px" class="cls_004"><span class="cls_004">typically implement a validation error interface too.</span></div>
<div style="position:absolute;left:5.00px;top:328.50px" class="cls_004"><span class="cls_004">They also differ from the main application View Models because they generally provide no</span></div>
<div style="position:absolute;left:5.00px;top:346.50px" class="cls_004"><span class="cls_004">functionality other than validation to their associated Views. We can think of these classes</span></div>
<div style="position:absolute;left:5.00px;top:364.50px" class="cls_004"><span class="cls_004">as mere data containers with a few extra properties to enable effective communication with</span></div>
<div style="position:absolute;left:5.00px;top:382.50px" class="cls_004"><span class="cls_004">the UI.</span></div>
<div style="position:absolute;left:5.00px;top:400.50px" class="cls_004"><span class="cls_004">When following this structure, we can render these individual object-sized View Models in</span></div>
<div style="position:absolute;left:5.00px;top:418.50px" class="cls_004"><span class="cls_004">the UI using data templates, so we generally don't need to declare a separate View for</span></div>
<div style="position:absolute;left:5.00px;top:436.50px" class="cls_004"><span class="cls_004">each of them. Furthermore, we may want to display the same objects differently in different</span></div>
<div style="position:absolute;left:5.00px;top:454.50px" class="cls_004"><span class="cls_004">parts of the application, or even switch their display in response to some user action and</span></div>
<div style="position:absolute;left:5.00px;top:472.50px" class="cls_004"><span class="cls_004">that is also easier to accomplish with data templates.</span></div>
<div style="position:absolute;left:5.00px;top:490.50px" class="cls_004"><span class="cls_004">This explains why these objects do not reside in the View Models project along with the</span></div>
<div style="position:absolute;left:5.00px;top:508.50px" class="cls_004"><span class="cls_004">main application View Models. If you remember, each View Model should only have one</span></div>
<div style="position:absolute;left:5.00px;top:526.50px" class="cls_004"><span class="cls_004">associated View. For the purpose of this book, this simpler, alternative implementation is</span></div>
<div style="position:absolute;left:5.00px;top:544.50px" class="cls_004"><span class="cls_004">the pattern that we will be following. Now, let's continue by investigating the DAL of the</span></div>
<div style="position:absolute;left:5.00px;top:562.50px" class="cls_004"><span class="cls_004">application.</span></div>
<div style="position:absolute;left:5.00px;top:580.50px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">DataProviders</span><span class="cls_004"> project from the first example is responsible for providing access to the</span></div>
<div style="position:absolute;left:5.00px;top:598.50px" class="cls_004"><span class="cls_004">persisted data source of the application. Another commonly used name is </span><span class="cls_007">Repositories</span><span class="cls_004">,</span></div>
<div style="position:absolute;left:5.00px;top:616.50px" class="cls_004"><span class="cls_004">but again, you can call it what you like. The important thing is that it has an essential</span></div>
<div style="position:absolute;left:5.00px;top:634.50px" class="cls_007"><span class="cls_007">Interfaces</span><span class="cls_004"> folder that contains one or more interfaces that form the connection between</span></div>
<div style="position:absolute;left:5.00px;top:652.50px" class="cls_004"><span class="cls_004">the data source(s) and the rest of the application.</span></div>
<div style="position:absolute;left:5.00px;top:670.50px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">DataProviders</span><span class="cls_004"> and </span><span class="cls_007">Interfaces</span><span class="cls_004"> folders in the second example appear within the </span><span class="cls_007">Models</span></div>
<div style="position:absolute;left:5.00px;top:688.50px" class="cls_004"><span class="cls_004">project, but they have the same responsibilities. Either way, it is through the use of these</span></div>
<div style="position:absolute;left:5.00px;top:706.50px" class="cls_004"><span class="cls_004">interfaces that we are able to disconnect the data source and replace it with a mock source</span></div>
<div style="position:absolute;left:5.00px;top:724.50px" class="cls_004"><span class="cls_004">of some kind when testing. We will look at an example of this in </span><span class="cls_015">Chapter 3</span><span class="cls_004">, </span><span class="cls_006">Writing Custom</span></div>
<div style="position:absolute;left:5.00px;top:743.25px" class="cls_006"><span class="cls_006">Application Frameworks</span><span class="cls_004">, but for now, let's continue.</span></div>
<div style="position:absolute;left:5.00px;top:762.00px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">ViewModels</span><span class="cls_004"> project is fairly easy to understand, as it just contains View Models. You</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:33684px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background044.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">may be wondering why there is a </span><span class="cls_007">Commands</span><span class="cls_004"> folder inside it. If we were using commands in</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">the old fashioned way, writing a separate class for each command, then we could end up</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">with a great many classes and that would probably warrant putting them into their own</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">project.</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">However, if you remember, we will be using only one single command, the </span><span class="cls_007">ActionCommand</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">As this will be used by the View Model classes alone, it makes sense to include it in their</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">project. We've already covered the differences in the View Models and Views projects</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">between the two example structures, so let's finish off looking at the remaining common</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">parts.</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">We often find an </span><span class="cls_007">Attached</span><span class="cls_004"> folder in the </span><span class="cls_007">Views</span><span class="cls_004"> project that contains the Attached Properties</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">that are used in the application. As these classes contain View-related code and are only</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">used by the Views, it is logical that they should reside here. Alongside that, we see the</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_007"><span class="cls_007">Controls</span><span class="cls_004"> folder where we find reusable user controls and/or custom controls, such as a</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">custom textbox that spawns a child window to help with editing when clicked or a custom</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">clock face that can be used to enter a time.</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">At the bottom of both example structures, we see the test projects that contain the code</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">that tests our application. If your application needs testing, this is a good pattern to follow.</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">By prefixing the name of the projects that we will be testing with a </span><span class="cls_007">Test</span><span class="cls_004"> domain, they will all</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_004"><span class="cls_004">appear in the Visual Studio Solution Explorer in one group, either above or below the other</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_004"><span class="cls_004">projects, and in the same order as the projects being tested.</span></div>
<div style="position:absolute;left:5.00px;top:363.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">Mocks</span><span class="cls_004"> project typically hosts the application objects to be used while testing the</span></div>
<div style="position:absolute;left:5.00px;top:381.75px" class="cls_004"><span class="cls_004">application. This would normally include any mock data generation or provider classes and</span></div>
<div style="position:absolute;left:5.00px;top:399.75px" class="cls_004"><span class="cls_004">mock </span><span class="cls_007">Manager</span><span class="cls_004"> classes. We may need to create these mock </span><span class="cls_007">Manager</span><span class="cls_004"> classes if we don't</span></div>
<div style="position:absolute;left:5.00px;top:417.75px" class="cls_004"><span class="cls_004">want to use expensive resources while testing, or in case they access any UI elements that</span></div>
<div style="position:absolute;left:5.00px;top:435.75px" class="cls_004"><span class="cls_004">we also want to avoid when testing. Let's take a look at an example of one possible method</span></div>
<div style="position:absolute;left:5.00px;top:453.75px" class="cls_004"><span class="cls_004">of a </span><span class="cls_007">UiThreadManager</span><span class="cls_004"> class:</span></div>
<div style="position:absolute;left:52.98px;top:477.00px" class="cls_007"><span class="cls_007">public Task RunAsynchronously(Action method)</span></div>
<div style="position:absolute;left:52.98px;top:490.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:504.00px" class="cls_007"><span class="cls_007">return Task.Run(method);</span></div>
<div style="position:absolute;left:52.98px;top:517.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:537.75px" class="cls_004"><span class="cls_004">This method is fairly straightforward and enables us to pass a reference to any method that</span></div>
<div style="position:absolute;left:5.00px;top:555.75px" class="cls_004"><span class="cls_004">we want to run asynchronously. It simply passes the method reference to the </span><span class="cls_007">Task.Run</span></div>
<div style="position:absolute;left:5.00px;top:573.75px" class="cls_004"><span class="cls_004">method and lets it do its thing. It can be called like this:</span></div>
<div style="position:absolute;left:52.98px;top:597.00px" class="cls_007"><span class="cls_007">UiThreadManager.RunAsynchronously(() => GenerateReports());</span></div>
<div style="position:absolute;left:5.00px;top:617.25px" class="cls_004"><span class="cls_004">However, running code asynchronously in unit tests can have unpredictable results that may</span></div>
<div style="position:absolute;left:5.00px;top:635.25px" class="cls_004"><span class="cls_004">make them fail. Therefore, when testing, we need to use a </span><span class="cls_007">MockUiThreadManager</span><span class="cls_004"> class and</span></div>
<div style="position:absolute;left:5.00px;top:653.25px" class="cls_004"><span class="cls_004">implement its </span><span class="cls_007">RunAsynchronously</span><span class="cls_004"> method, as follows:</span></div>
<div style="position:absolute;left:52.98px;top:676.50px" class="cls_007"><span class="cls_007">public Task RunAsynchronously(Action method)</span></div>
<div style="position:absolute;left:52.98px;top:690.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:703.50px" class="cls_007"><span class="cls_007">Task task = new Task(method);</span></div>
<div style="position:absolute;left:67.97px;top:717.00px" class="cls_007"><span class="cls_007">task.RunSynchronously();</span></div>
<div style="position:absolute;left:67.97px;top:730.50px" class="cls_007"><span class="cls_007">return task;</span></div>
<div style="position:absolute;left:52.98px;top:744.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:764.25px" class="cls_004"><span class="cls_004">In this method, we can see that we use the </span><span class="cls_007">RunSynchronously</span><span class="cls_004"> method of the </span><span class="cls_007">Task</span><span class="cls_004"> class to</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:34486px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background045.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">run the referenced method synchronously, or in other words, immediately and on the same</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">thread. In effect, this simply bypasses the functionality of the original method. Using these</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">mock objects enable us to run different code while testing than we do at runtime. We'll see</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">more examples of these mock objects in </span><span class="cls_015">Chapter 3</span><span class="cls_004">, </span><span class="cls_006">Writing Custom Application</span></div>
<div style="position:absolute;left:5.00px;top:76.50px" class="cls_006"><span class="cls_006">Frameworks</span><span class="cls_004">, but let's first take a look back at what we have covered so far.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:35288px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background046.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_008"><span class="cls_008">Summary</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">In this chapter, we have discovered what the MVVM architectural pattern is and the benefits</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">of using it when developing WPF applications. We're now in a better position to decide</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">which applications to use it with and which not to. We started looking into the various new</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">ways of communicating between the various components of this pattern and also</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">investigated the most common ways of organizing our source code. We are now ready to</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">start setting out our own application structures.</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">In the next chapter, before we properly get started building our application, we'll look at</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">several methods of the sometimes tricky task of debugging our data bound values. We'll</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">discover other useful tips and tricks that we can use to help us to iron out any problems that</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">may occur in our applications so that once we start building, we'll be able to avoid wasting</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">time with problems that may arise.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:36090px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background047.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_002"><span class="cls_002">Chapter 2. Debugging WPF Applications</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">When our WPF programs don't work as expected, we need to debug them, as we would</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">with any other language. However, at first it can seem to be a daunting task, as WPF is</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">very different from other languages. For example, when declaring a Dependency Property,</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">we normally add a CLR property wrapper for convenience. However, the WPF Framework</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">won't call it when the property value is changing, so we'd wait a long time for a break point</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">in that setter to be hit.</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">When we're testing our newly developed code, we need to be able to check the values of</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">our data bound properties, and there are a number of ways to do that, although some are</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">far from obvious. In this chapter, we'll investigate a number of important sources of</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">information to help us to locate the mistakes in our code.</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">We'll discover a variety of tactics to help us when debugging the data bound values and find</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">out how to track down the actual cause of a problem when faced with the dreaded</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_007"><span class="cls_007">XamlParseException</span><span class="cls_004">. We'll cover all of these topics in detail shortly, but for now, let's first</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">start with the absolute basics.</span></div>
<div style="position:absolute;left:5.00px;top:291.01px" class="cls_008"><span class="cls_008">Utilizing the Output window</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_004"><span class="cls_004">When we've made changes to our XAML, but don't see what we are expecting to see in the</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_004"><span class="cls_004">UI, the first place to look for errors is in the </span><span class="cls_005">Output</span><span class="cls_004"> window of Visual Studio. If this window</span></div>
<div style="position:absolute;left:5.00px;top:364.50px" class="cls_004"><span class="cls_004">is not already visible, then you can display it by selecting the </span><span class="cls_005">Output</span><span class="cls_004"> option from the </span><span class="cls_005">View</span></div>
<div style="position:absolute;left:5.00px;top:383.25px" class="cls_004"><span class="cls_004">menu or by pressing </span><span class="cls_012">Ctrl</span><span class="cls_006"> </span><span class="cls_004">+ </span><span class="cls_012">W</span><span class="cls_006"> </span><span class="cls_004">and then </span><span class="cls_012">O</span><span class="cls_006"> </span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:402.00px" class="cls_004"><span class="cls_004">However, if you have a binding error, but don't see any reference to it in the </span><span class="cls_005">Output</span></div>
<div style="position:absolute;left:5.00px;top:420.75px" class="cls_004"><span class="cls_004">window, it could be because your Visual Studio is not currently set up to output debug</span></div>
<div style="position:absolute;left:5.00px;top:438.75px" class="cls_004"><span class="cls_004">information to it. You can turn this functionality on in the Visual Studio </span><span class="cls_005">Options</span><span class="cls_004"> dialog</span></div>
<div style="position:absolute;left:5.00px;top:457.50px" class="cls_004"><span class="cls_004">window.</span></div>
<div style="position:absolute;left:17.00px;top:475.50px" class="cls_010"><span class="cls_010">Note</span></div>
<div style="position:absolute;left:17.00px;top:501.00px" class="cls_004"><span class="cls_004">Navigate to </span><span class="cls_005">Tools</span><span class="cls_004"> | </span><span class="cls_005">Options</span><span class="cls_004"> | </span><span class="cls_005">Debugging</span><span class="cls_004"> | </span><span class="cls_005">Output Window</span><span class="cls_004"> | </span><span class="cls_005">General Output</span></div>
<div style="position:absolute;left:17.00px;top:519.75px" class="cls_005"><span class="cls_005">Settings</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:539.25px" class="cls_004"><span class="cls_004">The </span><span class="cls_005">General Output Settings</span><span class="cls_004"> section has several options that you can turn on and off. The</span></div>
<div style="position:absolute;left:5.00px;top:558.00px" class="cls_004"><span class="cls_004">most important ones are </span><span class="cls_005">All debug output</span><span class="cls_004"> and </span><span class="cls_005">Exception Messages</span><span class="cls_004">, but it is generally</span></div>
<div style="position:absolute;left:5.00px;top:576.75px" class="cls_004"><span class="cls_004">good practice to leave them all set to </span><span class="cls_005">On</span><span class="cls_004">. When set, binding errors will be displayed in the</span></div>
<div style="position:absolute;left:5.00px;top:595.50px" class="cls_005"><span class="cls_005">Output</span><span class="cls_004"> window in the following format:</span></div>
<div style="position:absolute;left:52.98px;top:619.50px" class="cls_009"><span class="cls_009">System.Windows.Data Error: 40 : BindingExpression path error:</span></div>
<div style="position:absolute;left:52.98px;top:633.75px" class="cls_009"><span class="cls_009">'ViewName' property not found on 'object' ''MainViewModel'</span></div>
<div style="position:absolute;left:52.98px;top:648.00px" class="cls_009"><span class="cls_009">(HashCode=3910657)'. BindingExpression:Path=ViewName;</span></div>
<div style="position:absolute;left:52.98px;top:662.25px" class="cls_009"><span class="cls_009">DataItem='MainViewModel' (HashCode=3910657); target element is</span></div>
<div style="position:absolute;left:52.98px;top:675.75px" class="cls_009"><span class="cls_009">'TextBox'</span></div>
<div style="position:absolute;left:52.98px;top:690.00px" class="cls_009"><span class="cls_009">(Name='NameTextBox'); target property is 'Text' (type</span></div>
<div style="position:absolute;left:52.98px;top:704.25px" class="cls_009"><span class="cls_009">'String')</span></div>
<div style="position:absolute;left:5.00px;top:725.25px" class="cls_004"><span class="cls_004">Let's take a closer look at this error. The plain English translation for this would be as</span></div>
<div style="position:absolute;left:5.00px;top:743.25px" class="cls_004"><span class="cls_004">follows:</span></div>
<div style="position:absolute;left:34.99px;top:761.25px" class="cls_004"><span class="cls_004">There is no public property named </span><span class="cls_007">ViewName</span><span class="cls_004"> in the object of type </span><span class="cls_007">MainViewModel</span><span class="cls_004"> with a</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:36892px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background048.jpg" width=612 height=792></div>
<div style="position:absolute;left:34.99px;top:3.75px" class="cls_007"><span class="cls_007">HashCode</span><span class="cls_004"> value of </span><span class="cls_007">3910657</span></div>
<div style="position:absolute;left:34.99px;top:21.75px" class="cls_004"><span class="cls_004">The error was raised from a </span><span class="cls_007">Binding.Path</span><span class="cls_004"> value that was specified as </span><span class="cls_007">ViewName</span><span class="cls_004">, which</span></div>
<div style="position:absolute;left:34.99px;top:39.75px" class="cls_004"><span class="cls_004">was set on the </span><span class="cls_007">Text</span><span class="cls_004"> property of a </span><span class="cls_007">TextBox</span><span class="cls_004"> named </span><span class="cls_007">NameTextBox</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">This could be rewritten with descriptive names rather than specific details, like this:</span></div>
<div style="position:absolute;left:52.98px;top:81.00px" class="cls_009"><span class="cls_009">System.Windows.Data Error: 40 : BindingExpression path error:</span></div>
<div style="position:absolute;left:52.98px;top:95.25px" class="cls_009"><span class="cls_009">'PropertyOfBindingSource' property not found on 'object'</span></div>
<div style="position:absolute;left:52.98px;top:109.50px" class="cls_009"><span class="cls_009">''TypeOfBindingSource' (HashCode=HashCodeOfBindingSource)'.</span></div>
<div style="position:absolute;left:52.98px;top:123.75px" class="cls_009"><span class="cls_009">BindingExpression:Path=UsedBindingPath;</span></div>
<div style="position:absolute;left:52.98px;top:138.00px" class="cls_009"><span class="cls_009">DataItem='TypeOfBindingSource'</span></div>
<div style="position:absolute;left:52.98px;top:152.25px" class="cls_009"><span class="cls_009">(HashCode=HashCodeOfBindingSource); target element is</span></div>
<div style="position:absolute;left:52.98px;top:166.50px" class="cls_009"><span class="cls_009">'TypeOfBindingTarget' (Name='NameOfBindingTarget'); target</span></div>
<div style="position:absolute;left:52.98px;top:180.00px" class="cls_009"><span class="cls_009">property is</span></div>
<div style="position:absolute;left:52.98px;top:194.25px" class="cls_009"><span class="cls_009">'PropertyOfBindingTarget' (type</span></div>
<div style="position:absolute;left:52.98px;top:208.50px" class="cls_009"><span class="cls_009">'TypeOfBindingTargetProperty')</span></div>
<div style="position:absolute;left:5.00px;top:229.50px" class="cls_004"><span class="cls_004">Now that we have our 'key' to explain what these values represent, we can see that they</span></div>
<div style="position:absolute;left:5.00px;top:247.50px" class="cls_004"><span class="cls_004">are really very descriptive. Not only are we provided with the name of the data bound UI</span></div>
<div style="position:absolute;left:5.00px;top:265.50px" class="cls_004"><span class="cls_004">control, if it is set, and the used binding path, but also the type of the data source, along</span></div>
<div style="position:absolute;left:5.00px;top:283.50px" class="cls_004"><span class="cls_004">with the hash code of the actual instance of that type that is being used.</span></div>
<div style="position:absolute;left:5.00px;top:301.50px" class="cls_004"><span class="cls_004">These errors highlight the mistakes that have been made in the XAML files. The type of</span></div>
<div style="position:absolute;left:5.00px;top:319.50px" class="cls_004"><span class="cls_004">errors displayed in this window will include incorrectly labeled binding paths, such as using</span></div>
<div style="position:absolute;left:5.00px;top:337.50px" class="cls_004"><span class="cls_004">non-existent property names, or otherwise invalid binding source paths. While it won't catch</span></div>
<div style="position:absolute;left:5.00px;top:355.50px" class="cls_004"><span class="cls_004">every problem, there is a way to make it output additional information that could help us to</span></div>
<div style="position:absolute;left:5.00px;top:373.50px" class="cls_004"><span class="cls_004">track down our more elusive problems. In order to do this, first display the following</span></div>
<div style="position:absolute;left:5.00px;top:391.50px" class="cls_005"><span class="cls_005">Options</span><span class="cls_004"> dialog window:</span></div>
<div style="position:absolute;left:17.00px;top:410.25px" class="cls_010"><span class="cls_010">Note</span></div>
<div style="position:absolute;left:17.00px;top:435.75px" class="cls_004"><span class="cls_004">Navigate to </span><span class="cls_005">Tools</span><span class="cls_004"> | </span><span class="cls_005">Options</span><span class="cls_004"> | </span><span class="cls_005">Debugging</span><span class="cls_004"> | </span><span class="cls_005">Output Window</span><span class="cls_004"> | </span><span class="cls_005">WPF Trace Settings</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:455.25px" class="cls_004"><span class="cls_004">Here, you can find a number of options, each with a variable level of output; </span><span class="cls_005">Animation</span><span class="cls_004">,</span></div>
<div style="position:absolute;left:5.00px;top:474.00px" class="cls_005"><span class="cls_005">Data Binding</span><span class="cls_004">, </span><span class="cls_005">Dependency Properties</span><span class="cls_004">, </span><span class="cls_005">Documents</span><span class="cls_004">, </span><span class="cls_005">Freezable</span><span class="cls_004">, </span><span class="cls_005">HWND Hosting</span><span class="cls_004">,</span></div>
<div style="position:absolute;left:5.00px;top:492.75px" class="cls_005"><span class="cls_005">Markup</span><span class="cls_004">, </span><span class="cls_005">Name Scope</span><span class="cls_004">, </span><span class="cls_005">Resource Dictionaries</span><span class="cls_004"> and </span><span class="cls_005">Routed Events</span><span class="cls_004">. The various levels of</span></div>
<div style="position:absolute;left:5.00px;top:511.50px" class="cls_004"><span class="cls_004">output and their meanings are as follows:</span></div>
<div style="position:absolute;left:34.99px;top:529.50px" class="cls_005"><span class="cls_005">Critical</span><span class="cls_004">: Enables tracing of </span><span class="cls_005">Critical</span><span class="cls_004"> events only</span></div>
<div style="position:absolute;left:34.99px;top:548.25px" class="cls_005"><span class="cls_005">Error</span><span class="cls_004">: Enables tracing of </span><span class="cls_005">Critical</span><span class="cls_004"> and </span><span class="cls_005">Error</span><span class="cls_004"> events</span></div>
<div style="position:absolute;left:34.99px;top:567.00px" class="cls_005"><span class="cls_005">Warning</span><span class="cls_004">: Enables tracing of </span><span class="cls_005">Critical</span><span class="cls_004">, </span><span class="cls_005">Error</span><span class="cls_004">, and </span><span class="cls_005">Warning</span><span class="cls_004"> events</span></div>
<div style="position:absolute;left:34.99px;top:585.75px" class="cls_005"><span class="cls_005">Information</span><span class="cls_004">: Enables tracing of </span><span class="cls_005">Critical</span><span class="cls_004">, </span><span class="cls_005">Error</span><span class="cls_004">, </span><span class="cls_005">Warning</span><span class="cls_004">, and </span><span class="cls_005">Information</span><span class="cls_004"> events</span></div>
<div style="position:absolute;left:34.99px;top:604.50px" class="cls_005"><span class="cls_005">Verbose</span><span class="cls_004">: Enables tracing of </span><span class="cls_005">Critical</span><span class="cls_004">, </span><span class="cls_005">Error</span><span class="cls_004">, </span><span class="cls_005">Warning</span><span class="cls_004">, </span><span class="cls_005">Information</span><span class="cls_004">, and </span><span class="cls_005">Verbose</span></div>
<div style="position:absolute;left:34.99px;top:623.25px" class="cls_004"><span class="cls_004">events</span></div>
<div style="position:absolute;left:34.99px;top:641.25px" class="cls_005"><span class="cls_005">ActivityTracing</span><span class="cls_004">: Enables tracing of </span><span class="cls_005">Stop</span><span class="cls_004">, </span><span class="cls_005">Start</span><span class="cls_004">, </span><span class="cls_005">Suspend</span><span class="cls_004">, </span><span class="cls_005">Transfer</span><span class="cls_004">, and </span><span class="cls_005">Resume</span></div>
<div style="position:absolute;left:34.99px;top:660.00px" class="cls_004"><span class="cls_004">events</span></div>
<div style="position:absolute;left:5.00px;top:678.00px" class="cls_004"><span class="cls_004">It is fairly common to permanently have the </span><span class="cls_005">Data Binding</span><span class="cls_004"> option set to </span><span class="cls_005">Warning</span><span class="cls_004"> or </span><span class="cls_005">Error</span><span class="cls_004">,</span></div>
<div style="position:absolute;left:5.00px;top:696.75px" class="cls_004"><span class="cls_004">with the other options set to </span><span class="cls_005">Off</span><span class="cls_004">. The general rule of thumb when using these options is to</span></div>
<div style="position:absolute;left:5.00px;top:715.50px" class="cls_004"><span class="cls_004">use the minimum level required, except when trying to find problems, because they will slow</span></div>
<div style="position:absolute;left:5.00px;top:733.50px" class="cls_004"><span class="cls_004">down the running of the application. It should be noted however, that this extra debug trace</span></div>
<div style="position:absolute;left:5.00px;top:751.50px" class="cls_004"><span class="cls_004">output will not affect Release builds at all.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:37694px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background049.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">If you set the </span><span class="cls_005">Data Binding</span><span class="cls_004"> entry to an output of </span><span class="cls_005">Verbose</span><span class="cls_004"> or </span><span class="cls_005">All</span><span class="cls_004"> and look in the </span><span class="cls_005">Output</span></div>
<div style="position:absolute;left:5.00px;top:22.50px" class="cls_004"><span class="cls_004">window when running your application, you will understand why it will negatively affect</span></div>
<div style="position:absolute;left:5.00px;top:40.50px" class="cls_004"><span class="cls_004">performance. Even when not displaying this debug information in the </span><span class="cls_005">Output</span><span class="cls_004"> window, the</span></div>
<div style="position:absolute;left:5.00px;top:59.25px" class="cls_004"><span class="cls_004">WPF Framework will still be performing a great number of checks when there are binding</span></div>
<div style="position:absolute;left:5.00px;top:77.25px" class="cls_004"><span class="cls_004">errors. It is, therefore, very important to clear up all errors and warnings that are displayed,</span></div>
<div style="position:absolute;left:5.00px;top:95.25px" class="cls_004"><span class="cls_004">to minimize the amount of work that the Framework does when trying to resolve them.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:38496px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background050.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_008"><span class="cls_008">Putting Presentation Trace Sources to</span></div>
<div style="position:absolute;left:5.00px;top:39.01px" class="cls_008"><span class="cls_008">work</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">As useful as it is, there are certain occasions when using the </span><span class="cls_005">Output</span><span class="cls_004"> window will not</span></div>
<div style="position:absolute;left:5.00px;top:94.50px" class="cls_004"><span class="cls_004">suffice. Perhaps we have far too much output to look through now and would like to view it</span></div>
<div style="position:absolute;left:5.00px;top:112.50px" class="cls_004"><span class="cls_004">on the way home from work, or maybe we need to see this kind of debug trace information</span></div>
<div style="position:absolute;left:5.00px;top:130.50px" class="cls_004"><span class="cls_004">after our application has been deployed. In these cases and others, it's time to enable the</span></div>
<div style="position:absolute;left:5.00px;top:148.50px" class="cls_004"><span class="cls_004">WPF Presentation Trace Sources.</span></div>
<div style="position:absolute;left:5.00px;top:166.50px" class="cls_004"><span class="cls_004">There are a number of different trace sources that we can employ to output detailed tracing</span></div>
<div style="position:absolute;left:5.00px;top:184.50px" class="cls_004"><span class="cls_004">data for us. The choice is the same as that found in the </span><span class="cls_005">WPF Trace Settings</span><span class="cls_004"> options and in</span></div>
<div style="position:absolute;left:5.00px;top:203.25px" class="cls_004"><span class="cls_004">fact, after setting the values there, the </span><span class="cls_005">Output</span><span class="cls_004"> window has already been showing us the</span></div>
<div style="position:absolute;left:5.00px;top:222.00px" class="cls_004"><span class="cls_004">debug trace output. By default, WPF uses a </span><span class="cls_007">DefaultTraceListener</span><span class="cls_004"> object to send the</span></div>
<div style="position:absolute;left:5.00px;top:240.00px" class="cls_004"><span class="cls_004">information to the </span><span class="cls_005">Output</span><span class="cls_004"> window, but we can override that and/or configure the output to</span></div>
<div style="position:absolute;left:5.00px;top:258.75px" class="cls_004"><span class="cls_004">be sent to a text and/or XML file instead or as well.</span></div>
<div style="position:absolute;left:5.00px;top:276.75px" class="cls_004"><span class="cls_004">In order to do this, we need to alter our </span><span class="cls_007">app.config</span><span class="cls_004"> file, which is found in the root folder of</span></div>
<div style="position:absolute;left:5.00px;top:294.75px" class="cls_004"><span class="cls_004">our startup project. We'll need to add a </span><span class="cls_007">system.diagnostics</span><span class="cls_004"> section and within it, add</span></div>
<div style="position:absolute;left:5.00px;top:312.75px" class="cls_007"><span class="cls_007">sources</span><span class="cls_004">, </span><span class="cls_007">switches</span><span class="cls_004">, and </span><span class="cls_007">sharedlisteners</span><span class="cls_004"> elements. The </span><span class="cls_007">switches</span><span class="cls_004"> element holds the switch</span></div>
<div style="position:absolute;left:5.00px;top:330.75px" class="cls_004"><span class="cls_004">that determines the output level, as specified in the previous section.</span></div>
<div style="position:absolute;left:5.00px;top:348.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">sharedlisteners</span><span class="cls_004"> element specifies which kind of output we want to utilize. The three</span></div>
<div style="position:absolute;left:5.00px;top:366.75px" class="cls_004"><span class="cls_004">types are:</span></div>
<div style="position:absolute;left:34.99px;top:384.75px" class="cls_007"><span class="cls_007">System.Diagnostics.ConsoleTraceListener</span><span class="cls_004">: Sends the traces to the </span><span class="cls_005">Output</span><span class="cls_004"> window</span></div>
<div style="position:absolute;left:34.99px;top:403.50px" class="cls_007"><span class="cls_007">System.Diagnostics.TextWriterTraceListener</span><span class="cls_004">: Outputs to a text file</span></div>
<div style="position:absolute;left:34.99px;top:421.50px" class="cls_007"><span class="cls_007">System.Diagnostics.XmlWriterTraceListener</span><span class="cls_004">: Outputs to an XML file</span></div>
<div style="position:absolute;left:5.00px;top:439.50px" class="cls_004"><span class="cls_004">Finally, we need to add a </span><span class="cls_007">source</span><span class="cls_004"> element for each trace source that we want to listen to,</span></div>
<div style="position:absolute;left:5.00px;top:457.50px" class="cls_004"><span class="cls_004">and specify which switch and listener we want to use with it. Therefore, we are able to</span></div>
<div style="position:absolute;left:5.00px;top:475.50px" class="cls_004"><span class="cls_004">output different trace sources to different media and with different levels of output. These</span></div>
<div style="position:absolute;left:5.00px;top:493.50px" class="cls_004"><span class="cls_004">trace sources are the same as those found in the </span><span class="cls_005">WPF Trace Settings</span><span class="cls_004"> options, although in</span></div>
<div style="position:absolute;left:5.00px;top:512.25px" class="cls_004"><span class="cls_004">the configuration file, we need to specify their full names.</span></div>
<div style="position:absolute;left:5.00px;top:530.25px" class="cls_004"><span class="cls_004">The choices are as follows:</span></div>
<div style="position:absolute;left:34.99px;top:551.25px" class="cls_007"><span class="cls_007">System.Windows.Media.Animation</span></div>
<div style="position:absolute;left:34.99px;top:569.25px" class="cls_007"><span class="cls_007">System.Windows.Data</span></div>
<div style="position:absolute;left:34.99px;top:587.25px" class="cls_007"><span class="cls_007">System.Windows.DependencyProperty</span></div>
<div style="position:absolute;left:34.99px;top:605.25px" class="cls_007"><span class="cls_007">System.Windows.Documents</span></div>
<div style="position:absolute;left:34.99px;top:623.25px" class="cls_007"><span class="cls_007">System.Windows.Freezable</span></div>
<div style="position:absolute;left:34.99px;top:641.25px" class="cls_007"><span class="cls_007">System.Windows.Interop.HwndHost</span></div>
<div style="position:absolute;left:34.99px;top:659.25px" class="cls_007"><span class="cls_007">System.Windows.Markup</span></div>
<div style="position:absolute;left:34.99px;top:677.25px" class="cls_007"><span class="cls_007">System.Windows.NameScope</span></div>
<div style="position:absolute;left:34.99px;top:695.25px" class="cls_007"><span class="cls_007">System.Windows.ResourceDictionary</span></div>
<div style="position:absolute;left:34.99px;top:713.25px" class="cls_007"><span class="cls_007">System.Windows.RoutedEvent</span></div>
<div style="position:absolute;left:34.99px;top:731.25px" class="cls_007"><span class="cls_007">System.Windows.Shell</span></div>
<div style="position:absolute;left:5.00px;top:746.25px" class="cls_004"><span class="cls_004">Let's see an example configuration file:</span></div>
<div style="position:absolute;left:52.98px;top:769.50px" class="cls_007"><span class="cls_007"><?xml version="1.0" encoding="utf-8"?></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:39298px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background051.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:3.00px" class="cls_007"><span class="cls_007"><configuration></span></div>
<div style="position:absolute;left:67.97px;top:16.50px" class="cls_007"><span class="cls_007"><startup></span></div>
<div style="position:absolute;left:82.97px;top:30.00px" class="cls_007"><span class="cls_007"><supportedRuntime version="v4.0"</span></div>
<div style="position:absolute;left:52.98px;top:43.50px" class="cls_007"><span class="cls_007">sku=".NETFramework,Version=v4.6.1" /></span></div>
<div style="position:absolute;left:67.97px;top:57.00px" class="cls_007"><span class="cls_007"></startup></span></div>
<div style="position:absolute;left:67.97px;top:70.50px" class="cls_007"><span class="cls_007"><system.diagnostics></span></div>
<div style="position:absolute;left:82.97px;top:84.00px" class="cls_007"><span class="cls_007"><sources></span></div>
<div style="position:absolute;left:97.96px;top:97.50px" class="cls_007"><span class="cls_007"><source name="System.Windows.Data" switchName="Switch"></span></div>
<div style="position:absolute;left:112.96px;top:111.00px" class="cls_007"><span class="cls_007"><listeners></span></div>
<div style="position:absolute;left:127.95px;top:124.50px" class="cls_007"><span class="cls_007"><add name="TextListener" /></span></div>
<div style="position:absolute;left:112.96px;top:138.00px" class="cls_007"><span class="cls_007"></listeners></span></div>
<div style="position:absolute;left:97.96px;top:151.50px" class="cls_007"><span class="cls_007"></source></span></div>
<div style="position:absolute;left:82.97px;top:165.00px" class="cls_007"><span class="cls_007"></sources></span></div>
<div style="position:absolute;left:82.97px;top:178.50px" class="cls_007"><span class="cls_007"><switches></span></div>
<div style="position:absolute;left:97.96px;top:192.00px" class="cls_007"><span class="cls_007"><add name="Switch" value="All" /></span></div>
<div style="position:absolute;left:82.97px;top:205.50px" class="cls_007"><span class="cls_007"></switches></span></div>
<div style="position:absolute;left:82.97px;top:219.00px" class="cls_007"><span class="cls_007"><sharedListeners></span></div>
<div style="position:absolute;left:97.96px;top:232.50px" class="cls_007"><span class="cls_007"><add name="TextListener"</span></div>
<div style="position:absolute;left:112.96px;top:246.00px" class="cls_007"><span class="cls_007">type="System.Diagnostics.TextWriterTraceListener"</span></div>
<div style="position:absolute;left:112.96px;top:259.50px" class="cls_007"><span class="cls_007">initializeData="Trace.txt" /></span></div>
<div style="position:absolute;left:82.97px;top:273.00px" class="cls_007"><span class="cls_007"></sharedListeners></span></div>
<div style="position:absolute;left:82.97px;top:286.50px" class="cls_007"><span class="cls_007"><trace indentsize="4" autoflush="true"></trace></span></div>
<div style="position:absolute;left:67.97px;top:300.00px" class="cls_007"><span class="cls_007"></system.diagnostics></span></div>
<div style="position:absolute;left:52.98px;top:313.50px" class="cls_007"><span class="cls_007"></configuration></span></div>
<div style="position:absolute;left:5.00px;top:333.75px" class="cls_004"><span class="cls_004">Focusing on the </span><span class="cls_007">system.diagnostics</span><span class="cls_004"> section from the example, we see that there is one</span></div>
<div style="position:absolute;left:5.00px;top:351.75px" class="cls_004"><span class="cls_004">source element that is specifying the </span><span class="cls_007">System.Windows.Data</span><span class="cls_004"> source (for data binding</span></div>
<div style="position:absolute;left:5.00px;top:369.75px" class="cls_004"><span class="cls_004">information), the switch named </span><span class="cls_007">Switch</span><span class="cls_004"> and the </span><span class="cls_007">TextListener</span><span class="cls_004"> listener. Looking first in the</span></div>
<div style="position:absolute;left:5.00px;top:387.75px" class="cls_007"><span class="cls_007">switches</span><span class="cls_004"> section, we find the switch named </span><span class="cls_007">Switch</span><span class="cls_004">, and note that it is set with an output</span></div>
<div style="position:absolute;left:5.00px;top:405.75px" class="cls_004"><span class="cls_004">level of </span><span class="cls_007">All</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:423.75px" class="cls_004"><span class="cls_004">Below this, in the </span><span class="cls_007">sharedlisteners</span><span class="cls_004"> element, we see the listener named </span><span class="cls_007">TextListener</span><span class="cls_004">. This</span></div>
<div style="position:absolute;left:5.00px;top:441.75px" class="cls_004"><span class="cls_004">listener is of type </span><span class="cls_007">System.Diagnostics.TextWriterTraceListener</span><span class="cls_004"> and this outputs to a text</span></div>
<div style="position:absolute;left:5.00px;top:459.75px" class="cls_004"><span class="cls_004">file which is specified by the value of the </span><span class="cls_007">initializeData</span><span class="cls_004"> attribute. We end with a </span><span class="cls_007">trace</span></div>
<div style="position:absolute;left:5.00px;top:477.75px" class="cls_004"><span class="cls_004">element that sets the tab size of the text document to four spaces and ensures that data is</span></div>
<div style="position:absolute;left:5.00px;top:495.75px" class="cls_004"><span class="cls_004">flushed out of the buffer after each write to prevent trace data being lost due to a crash.</span></div>
<div style="position:absolute;left:5.00px;top:513.75px" class="cls_004"><span class="cls_004">To set a less verbose output, we can simply alter the switch to use one of the other levels</span></div>
<div style="position:absolute;left:5.00px;top:531.75px" class="cls_004"><span class="cls_004">of output, as follows:</span></div>
<div style="position:absolute;left:52.98px;top:555.00px" class="cls_007"><span class="cls_007"><add name="Switch" value="Error" /></span></div>
<div style="position:absolute;left:5.00px;top:575.25px" class="cls_004"><span class="cls_004">As mentioned earlier, WPF can use a </span><span class="cls_007">DefaultTraceListener</span><span class="cls_004"> object to send trace</span></div>
<div style="position:absolute;left:5.00px;top:593.25px" class="cls_004"><span class="cls_004">information to the </span><span class="cls_005">Output</span><span class="cls_004"> window when particular options are set in Visual Studio. The</span></div>
<div style="position:absolute;left:5.00px;top:612.00px" class="cls_004"><span class="cls_004">name of this listener is </span><span class="cls_007">Default</span><span class="cls_004">. In order to stop the default behavior of this</span></div>
<div style="position:absolute;left:5.00px;top:630.00px" class="cls_007"><span class="cls_007">DefaultTraceListener</span><span class="cls_004">, we can remove it using our </span><span class="cls_007">source</span><span class="cls_004"> element, as follows:</span></div>
<div style="position:absolute;left:52.98px;top:653.25px" class="cls_007"><span class="cls_007"><source name="System.Windows.Data" switchName="Switch"></span></div>
<div style="position:absolute;left:67.97px;top:666.75px" class="cls_007"><span class="cls_007"><listeners></span></div>
<div style="position:absolute;left:82.97px;top:680.25px" class="cls_007"><span class="cls_007"><add name="TextListener" /></span></div>
<div style="position:absolute;left:82.97px;top:693.75px" class="cls_007"><span class="cls_007"><remove name="Default" /></span></div>
<div style="position:absolute;left:67.97px;top:707.25px" class="cls_007"><span class="cls_007"></listeners></span></div>
<div style="position:absolute;left:52.98px;top:720.75px" class="cls_007"><span class="cls_007"></source></span></div>
<div style="position:absolute;left:5.00px;top:741.00px" class="cls_004"><span class="cls_004">It's good to be aware of this fact, because if we also configured our own</span></div>
<div style="position:absolute;left:5.00px;top:759.00px" class="cls_007"><span class="cls_007">ConsoleTraceListener</span><span class="cls_004"> object, we could end up with our </span><span class="cls_005">Output</span><span class="cls_004"> window duplicating trace</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:40100px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background052.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">events. However, it is also possible to add multiple listeners into each </span><span class="cls_007">source</span><span class="cls_004"> element if</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">required.</span></div>
<div style="position:absolute;left:52.98px;top:45.00px" class="cls_007"><span class="cls_007"><source name="System.Windows.Data" switchName="Switch"></span></div>
<div style="position:absolute;left:67.97px;top:58.50px" class="cls_007"><span class="cls_007"><listeners></span></div>
<div style="position:absolute;left:82.97px;top:72.00px" class="cls_007"><span class="cls_007"><add name="TextListener" /></span></div>
<div style="position:absolute;left:82.97px;top:85.50px" class="cls_007"><span class="cls_007"><add name="OutputListener" /></span></div>
<div style="position:absolute;left:67.97px;top:99.00px" class="cls_007"><span class="cls_007"></listeners></span></div>
<div style="position:absolute;left:52.98px;top:112.50px" class="cls_007"><span class="cls_007"></source></span></div>
<div style="position:absolute;left:5.00px;top:132.75px" class="cls_004"><span class="cls_004">We can also add different listeners for different sources.</span></div>
<div style="position:absolute;left:52.98px;top:156.00px" class="cls_007"><span class="cls_007"><source name="System.Windows.Data" switchName="Switch"></span></div>
<div style="position:absolute;left:67.97px;top:169.50px" class="cls_007"><span class="cls_007"><listeners></span></div>
<div style="position:absolute;left:82.97px;top:183.00px" class="cls_007"><span class="cls_007"><add name="TextListener" /></span></div>
<div style="position:absolute;left:67.97px;top:196.50px" class="cls_007"><span class="cls_007"></listeners></span></div>
<div style="position:absolute;left:52.98px;top:210.00px" class="cls_007"><span class="cls_007"></source></span></div>
<div style="position:absolute;left:52.98px;top:223.50px" class="cls_007"><span class="cls_007"><source name="System.Windows.DependencyProperty"</span></div>
<div style="position:absolute;left:52.98px;top:237.00px" class="cls_007"><span class="cls_007">switchName="Switch"></span></div>
<div style="position:absolute;left:67.97px;top:250.50px" class="cls_007"><span class="cls_007"><listeners></span></div>
<div style="position:absolute;left:82.97px;top:264.00px" class="cls_007"><span class="cls_007"><add name="OutputListener" /></span></div>
<div style="position:absolute;left:67.97px;top:277.50px" class="cls_007"><span class="cls_007"></listeners></span></div>
<div style="position:absolute;left:52.98px;top:291.00px" class="cls_007"><span class="cls_007"></source></span></div>
<div style="position:absolute;left:52.98px;top:318.00px" class="cls_007"><span class="cls_007"><sharedListeners></span></div>
<div style="position:absolute;left:67.97px;top:331.50px" class="cls_007"><span class="cls_007"><add name="TextListener"</span></div>
<div style="position:absolute;left:82.97px;top:345.00px" class="cls_007"><span class="cls_007">type="System.Diagnostics.TextWriterTraceListener"</span></div>
<div style="position:absolute;left:82.97px;top:358.50px" class="cls_007"><span class="cls_007">initializeData="Trace.txt" /></span></div>
<div style="position:absolute;left:67.97px;top:372.00px" class="cls_007"><span class="cls_007"><add name="OutputListener"</span></div>
<div style="position:absolute;left:82.97px;top:385.50px" class="cls_007"><span class="cls_007">type="System.Diagnostics.ConsoleTraceListener" /></span></div>
<div style="position:absolute;left:52.98px;top:399.00px" class="cls_007"><span class="cls_007"></sharedListeners></span></div>
<div style="position:absolute;left:5.00px;top:419.25px" class="cls_004"><span class="cls_004">Different output levels for different sources can be added as follows:</span></div>
<div style="position:absolute;left:52.98px;top:442.50px" class="cls_007"><span class="cls_007"><source name="System.Windows.Data" switchName="ErrorSwitch"></span></div>
<div style="position:absolute;left:67.97px;top:456.00px" class="cls_007"><span class="cls_007"><listeners></span></div>
<div style="position:absolute;left:82.97px;top:469.50px" class="cls_007"><span class="cls_007"><add name="TextListener" /></span></div>
<div style="position:absolute;left:67.97px;top:483.00px" class="cls_007"><span class="cls_007"></listeners></span></div>
<div style="position:absolute;left:52.98px;top:496.50px" class="cls_007"><span class="cls_007"></source></span></div>
<div style="position:absolute;left:52.98px;top:510.00px" class="cls_007"><span class="cls_007"><source name="System.Windows.DependencyProperty"</span></div>
<div style="position:absolute;left:52.98px;top:523.50px" class="cls_007"><span class="cls_007">switchName="AllSwitch"></span></div>
<div style="position:absolute;left:67.97px;top:537.00px" class="cls_007"><span class="cls_007"><listeners></span></div>
<div style="position:absolute;left:82.97px;top:550.50px" class="cls_007"><span class="cls_007"><add name="OutputListener" /></span></div>
<div style="position:absolute;left:67.97px;top:564.00px" class="cls_007"><span class="cls_007"></listeners></span></div>
<div style="position:absolute;left:52.98px;top:577.50px" class="cls_007"><span class="cls_007"></source></span></div>
<div style="position:absolute;left:52.98px;top:604.50px" class="cls_007"><span class="cls_007"><switches></span></div>
<div style="position:absolute;left:67.97px;top:618.00px" class="cls_007"><span class="cls_007"><add name="AllSwitch" value="All" /></span></div>
<div style="position:absolute;left:67.97px;top:631.50px" class="cls_007"><span class="cls_007"><add name="ErrorSwitch" value="Error" /></span></div>
<div style="position:absolute;left:52.98px;top:645.00px" class="cls_007"><span class="cls_007"></switches></span></div>
<div style="position:absolute;left:5.00px;top:665.25px" class="cls_004"><span class="cls_004">One neat feature that the WPF Presentation Trace Sources provide is the ability to create</span></div>
<div style="position:absolute;left:5.00px;top:683.25px" class="cls_004"><span class="cls_004">our own custom trace sources.</span></div>
<div style="position:absolute;left:52.98px;top:706.50px" class="cls_007"><span class="cls_007"><source name="CompanyName.ApplicationName" switchName="Switch"></span></div>
<div style="position:absolute;left:67.97px;top:720.00px" class="cls_007"><span class="cls_007"><listeners></span></div>
<div style="position:absolute;left:82.97px;top:733.50px" class="cls_007"><span class="cls_007"><add name="TextListener" /></span></div>
<div style="position:absolute;left:67.97px;top:747.00px" class="cls_007"><span class="cls_007"></listeners></span></div>
<div style="position:absolute;left:52.98px;top:760.50px" class="cls_007"><span class="cls_007"></source></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:40902px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background053.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">Note that the </span><span class="cls_007">DefaultTraceListener</span><span class="cls_004"> was already configured to send information to the</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_005"><span class="cls_005">Output</span><span class="cls_004"> window in the </span><span class="cls_005">WPF Trace Settings</span><span class="cls_004"> options mentioned in the previous section, so</span></div>
<div style="position:absolute;left:5.00px;top:40.50px" class="cls_004"><span class="cls_004">the traces from this source will also be sent to the </span><span class="cls_005">Output</span><span class="cls_004"> window automatically. If you</span></div>
<div style="position:absolute;left:5.00px;top:59.25px" class="cls_004"><span class="cls_004">have not set those options, but want to view the trace output there, then you will need to</span></div>
<div style="position:absolute;left:5.00px;top:77.25px" class="cls_004"><span class="cls_004">manually add a reference to the </span><span class="cls_007">ConsoleTraceListener</span><span class="cls_004"> to this source as shown in the</span></div>
<div style="position:absolute;left:5.00px;top:95.25px" class="cls_004"><span class="cls_004">preceding code snippets.</span></div>
<div style="position:absolute;left:5.00px;top:113.25px" class="cls_004"><span class="cls_004">In code, we are now able to output custom trace information to this source.</span></div>
<div style="position:absolute;left:52.98px;top:136.50px" class="cls_007"><span class="cls_007">TraceSource traceSource = new</span></div>
<div style="position:absolute;left:52.98px;top:150.00px" class="cls_007"><span class="cls_007">TraceSource("CompanyName.ApplicationName");</span></div>
<div style="position:absolute;left:52.98px;top:163.50px" class="cls_007"><span class="cls_007">traceSource.TraceEvent(TraceEventType.Information, eventId, "Data</span></div>
<div style="position:absolute;left:52.98px;top:177.00px" class="cls_007"><span class="cls_007">loaded");</span></div>
<div style="position:absolute;left:52.98px;top:190.50px" class="cls_007"><span class="cls_007">// Alternative way to output information with an event id of 0</span></div>
<div style="position:absolute;left:52.98px;top:204.00px" class="cls_007"><span class="cls_007">traceSource.TraceInformation("Data loaded");</span></div>
<div style="position:absolute;left:5.00px;top:224.25px" class="cls_004"><span class="cls_004">To specify different levels of importance, we use the </span><span class="cls_007">TraceEventType</span><span class="cls_004"> enumeration.</span></div>
<div style="position:absolute;left:52.98px;top:247.50px" class="cls_007"><span class="cls_007">traceSource.TraceEvent(TraceEventType.Error, eventId, "Data not</span></div>
<div style="position:absolute;left:52.98px;top:261.00px" class="cls_007"><span class="cls_007">loaded");</span></div>
<div style="position:absolute;left:5.00px;top:281.25px" class="cls_004"><span class="cls_004">After outputting the debug information, we can optionally flush the existing listeners to</span></div>
<div style="position:absolute;left:5.00px;top:299.25px" class="cls_004"><span class="cls_004">ensure that they receive the events in the buffers before continuing.</span></div>
<div style="position:absolute;left:52.98px;top:322.50px" class="cls_007"><span class="cls_007">traceSource.Flush();</span></div>
<div style="position:absolute;left:5.00px;top:342.75px" class="cls_004"><span class="cls_004">Finally, we need to ensure that we close the </span><span class="cls_007">TraceSource</span><span class="cls_004"> object to free resources when we</span></div>
<div style="position:absolute;left:5.00px;top:360.75px" class="cls_004"><span class="cls_004">have outputted the necessary information.</span></div>
<div style="position:absolute;left:52.98px;top:384.00px" class="cls_007"><span class="cls_007">traceSource.Close();</span></div>
<div style="position:absolute;left:5.00px;top:404.25px" class="cls_004"><span class="cls_004">The best part of this tracing functionality is the fact that we can turn it on and off using the</span></div>
<div style="position:absolute;left:5.00px;top:422.25px" class="cls_004"><span class="cls_004">configuration file, either at design time, runtime, or even on production versions of the</span></div>
<div style="position:absolute;left:5.00px;top:440.25px" class="cls_004"><span class="cls_004">application. As the configuration file is basically a text file, we can manually edit it and then</span></div>
<div style="position:absolute;left:5.00px;top:458.25px" class="cls_004"><span class="cls_004">restart the application so that it reads the new configuration.</span></div>
<div style="position:absolute;left:5.00px;top:476.25px" class="cls_004"><span class="cls_004">Imagine that we had two switches in our file and that our default configuration used the</span></div>
<div style="position:absolute;left:5.00px;top:494.25px" class="cls_004"><span class="cls_004">switch named </span><span class="cls_007">OffSwitch</span><span class="cls_004">, so that there was no tracing output.</span></div>
<div style="position:absolute;left:52.98px;top:517.50px" class="cls_007"><span class="cls_007"><source name="CompanyName.ApplicationName" switchName="OffSwitch"></span></div>
<div style="position:absolute;left:67.97px;top:531.00px" class="cls_007"><span class="cls_007"><listeners></span></div>
<div style="position:absolute;left:82.97px;top:544.50px" class="cls_007"><span class="cls_007"><add name="TextListener" /></span></div>
<div style="position:absolute;left:67.97px;top:558.00px" class="cls_007"><span class="cls_007"></listeners></span></div>
<div style="position:absolute;left:52.98px;top:571.50px" class="cls_007"><span class="cls_007"></source></span></div>
<div style="position:absolute;left:52.98px;top:598.50px" class="cls_007"><span class="cls_007"><switches></span></div>
<div style="position:absolute;left:67.97px;top:612.00px" class="cls_007"><span class="cls_007"><add name="AllSwitch" value="All" /></span></div>
<div style="position:absolute;left:67.97px;top:625.50px" class="cls_007"><span class="cls_007"><add name="OffSwitch" value="Off" /></span></div>
<div style="position:absolute;left:52.98px;top:639.00px" class="cls_007"><span class="cls_007"></switches></span></div>
<div style="position:absolute;left:5.00px;top:659.25px" class="cls_004"><span class="cls_004">Now imagine that we have deployed our application and it is installed on a user's computer.</span></div>
<div style="position:absolute;left:5.00px;top:677.25px" class="cls_004"><span class="cls_004">It's worth noting at this point that the actual deployed configuration file that is created from</span></div>
<div style="position:absolute;left:5.00px;top:695.25px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">app.config</span><span class="cls_004"> file will have the same name as the executable file. In our case, it would be</span></div>
<div style="position:absolute;left:5.00px;top:713.25px" class="cls_004"><span class="cls_004">named </span><span class="cls_007">CompanyName.ApplicationName.exe.config</span><span class="cls_004"> and would reside in the same folder as</span></div>
<div style="position:absolute;left:5.00px;top:731.25px" class="cls_004"><span class="cls_004">the executable file.</span></div>
<div style="position:absolute;left:5.00px;top:749.25px" class="cls_004"><span class="cls_004">If this installed application was not behaving correctly, we could locate this configuration file,</span></div>
<div style="position:absolute;left:5.00px;top:767.25px" class="cls_004"><span class="cls_004">and simply change the switch to the one named </span><span class="cls_007">AllSwitch</span><span class="cls_004">.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:41704px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background054.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:7.50px" class="cls_007"><span class="cls_007"><source name="CompanyName.ApplicationName" switchName="AllSwitch"></span></div>
<div style="position:absolute;left:67.97px;top:21.00px" class="cls_007"><span class="cls_007"><listeners></span></div>
<div style="position:absolute;left:82.97px;top:34.50px" class="cls_007"><span class="cls_007"><add name="TextListener" /></span></div>
<div style="position:absolute;left:67.97px;top:48.00px" class="cls_007"><span class="cls_007"></listeners></span></div>
<div style="position:absolute;left:52.98px;top:61.50px" class="cls_007"><span class="cls_007"></source></span></div>
<div style="position:absolute;left:5.00px;top:81.75px" class="cls_004"><span class="cls_004">After restarting the application, the new configuration would be read and our custom traces</span></div>
<div style="position:absolute;left:5.00px;top:99.75px" class="cls_004"><span class="cls_004">would be written to the specified text file. One alternative to restarting the application would</span></div>
<div style="position:absolute;left:5.00px;top:117.75px" class="cls_004"><span class="cls_004">be to call the </span><span class="cls_007">Refresh</span><span class="cls_004"> method of the </span><span class="cls_007">Trace</span><span class="cls_004"> class, which has the same effect of initiating a</span></div>
<div style="position:absolute;left:5.00px;top:135.75px" class="cls_004"><span class="cls_004">new read of the configuration file.</span></div>
<div style="position:absolute;left:52.98px;top:159.00px" class="cls_007"><span class="cls_007">Trace.Refresh();</span></div>
<div style="position:absolute;left:5.00px;top:179.25px" class="cls_004"><span class="cls_004">This method call can even be connected to a menu item or other UI control to enable tracing</span></div>
<div style="position:absolute;left:5.00px;top:197.25px" class="cls_004"><span class="cls_004">to be turned on and off without having to restart the application. Using either of these</span></div>
<div style="position:absolute;left:5.00px;top:215.25px" class="cls_004"><span class="cls_004">methods of refreshing the configuration file, we can attain important debug information from</span></div>
<div style="position:absolute;left:5.00px;top:233.25px" class="cls_004"><span class="cls_004">our software, even when it is in production. However, great care should be taken to ensure</span></div>
<div style="position:absolute;left:5.00px;top:251.25px" class="cls_004"><span class="cls_004">that text or XML file tracing is not permanently enabled on released software, as it will</span></div>
<div style="position:absolute;left:5.00px;top:269.25px" class="cls_004"><span class="cls_004">negatively affect performance.</span></div>
<div style="position:absolute;left:5.00px;top:287.25px" class="cls_004"><span class="cls_004">While the WPF Presentation Trace Sources are typically available by default these days, in</span></div>
<div style="position:absolute;left:5.00px;top:305.25px" class="cls_004"><span class="cls_004">a few cases, we may need to manually enable this tracing functionality by adding the</span></div>
<div style="position:absolute;left:5.00px;top:323.25px" class="cls_004"><span class="cls_004">following registry key.</span></div>
<div style="position:absolute;left:52.98px;top:346.50px" class="cls_007"><span class="cls_007">HKEY_CURRENT_USER\Software\Microsoft\Tracing\WPF</span></div>
<div style="position:absolute;left:5.00px;top:366.75px" class="cls_004"><span class="cls_004">Once the </span><span class="cls_007">WPF</span><span class="cls_004"> registry key has been added, we need to add a new </span><span class="cls_007">DWORD</span><span class="cls_004"> value to it, name it</span></div>
<div style="position:absolute;left:5.00px;top:384.75px" class="cls_007"><span class="cls_007">ManagedTracing</span><span class="cls_004"> and set its value to </span><span class="cls_007">1</span><span class="cls_004">. We should then have access to the WPF</span></div>
<div style="position:absolute;left:5.00px;top:402.75px" class="cls_004"><span class="cls_004">Presentation Trace Sources. We've now seen a number of ways of finding the information</span></div>
<div style="position:absolute;left:5.00px;top:420.75px" class="cls_004"><span class="cls_004">that we need at runtime, but what about if the application won't even run?</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:42506px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background055.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_008"><span class="cls_008">Discovering inner exceptions</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">When we are building the content of our Views, we often make the odd typographical</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">mistake here and there. Perhaps, we mistype the name of one of our properties in a binding</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">path, or copy and paste some code that references other code that we have not copied.</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">At first, it may appear to be quite difficult to find the source of these types of errors,</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">because when we run our application, the actual error that is raised by Visual Studio is</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">usually of type </span><span class="cls_007">XamlParseException</span><span class="cls_004"> and bares no direct relation to the actual error. The</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">additional information provided is also of little help. Here is a typical example.</span></div>
<div style="position:absolute;left:5.00px;top:634.50px" class="cls_004"><span class="cls_004">Let's investigate this further. We can see that the additional information supplied here says-</span></div>
<div style="position:absolute;left:5.00px;top:651.75px" class="cls_007"><span class="cls_007">'Provide value on 'System.Windows.Markup.StaticResourceHolder' threw an</span></div>
<div style="position:absolute;left:5.00px;top:666.00px" class="cls_007"><span class="cls_007">exception.' Line number '48' and line position '41'</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:684.00px" class="cls_004"><span class="cls_004">Now let's try to break this down to some meaningful information. Firstly, it is clear that the</span></div>
<div style="position:absolute;left:5.00px;top:702.00px" class="cls_004"><span class="cls_004">exception was thrown by the </span><span class="cls_007">System.Windows.Markup.StaticResourceHolder</span><span class="cls_004"> class. By</span></div>
<div style="position:absolute;left:5.00px;top:720.00px" class="cls_004"><span class="cls_004">itself, this information is not very useful, but at least we know that the problem has</span></div>
<div style="position:absolute;left:5.00px;top:738.00px" class="cls_004"><span class="cls_004">something to do with a </span><span class="cls_007">StaticResource</span><span class="cls_004"> that could not be resolved.</span></div>
<div style="position:absolute;left:5.00px;top:756.00px" class="cls_004"><span class="cls_004">The next bit of information that we can gather from this message is that the problem</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:43308px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background056.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">occurred on line 48 and position 41. However, without informing us of which file this relates</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">to, this information is also not very useful. The </span><span class="cls_005">Exception</span><span class="cls_004"> dialog window shown in the</span></div>
<div style="position:absolute;left:5.00px;top:40.50px" class="cls_004"><span class="cls_004">preceding screenshot will often have a line pointing to the line and position in the current file,</span></div>
<div style="position:absolute;left:5.00px;top:58.50px" class="cls_004"><span class="cls_004">which can also be another red herring. In this particular case, it was indeed false</span></div>
<div style="position:absolute;left:5.00px;top:76.50px" class="cls_004"><span class="cls_004">information as there was no error there, but at least that tells us that the problem has not</span></div>
<div style="position:absolute;left:5.00px;top:94.50px" class="cls_004"><span class="cls_004">arisen from the current file.</span></div>
<div style="position:absolute;left:5.00px;top:112.50px" class="cls_004"><span class="cls_004">The trick to finding out what caused the real problem that occurred is for us to click the</span></div>
<div style="position:absolute;left:5.00px;top:130.50px" class="cls_005"><span class="cls_005">View Detail...</span><span class="cls_004"> link in the window. This will open the </span><span class="cls_005">View Detail</span><span class="cls_004"> window, where we can see</span></div>
<div style="position:absolute;left:5.00px;top:149.25px" class="cls_004"><span class="cls_004">all of the property values of the </span><span class="cls_007">XamlParseException</span><span class="cls_004">. Looking at the </span><span class="cls_007">StackTrace</span><span class="cls_004"> and</span></div>
<div style="position:absolute;left:5.00px;top:167.25px" class="cls_007"><span class="cls_007">TargetSite</span><span class="cls_004"> property values won't help in the way that they usually do with normal</span></div>
<div style="position:absolute;left:5.00px;top:185.25px" class="cls_004"><span class="cls_004">exceptions. However, if we open up and inspect the </span><span class="cls_007">InnerException</span><span class="cls_004"> property value, we can</span></div>
<div style="position:absolute;left:5.00px;top:203.25px" class="cls_004"><span class="cls_004">finally find out what actually happened. Let's do that with our example.</span></div>
<div style="position:absolute;left:5.00px;top:648.75px" class="cls_004"><span class="cls_004">At last, we have something that we can work with. The </span><span class="cls_007">InnerException.Message</span><span class="cls_004"> property</span></div>
<div style="position:absolute;left:5.00px;top:666.75px" class="cls_004"><span class="cls_004">value states: </span><span class="cls_007">"Cannot find resource named 'BaseButtonStyle'. Resource names are</span></div>
<div style="position:absolute;left:5.00px;top:684.75px" class="cls_007"><span class="cls_007">case sensitive"</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:702.75px" class="cls_004"><span class="cls_004">Therefore, our offending object references the </span><span class="cls_007">BaseButtonStyle</span><span class="cls_004"> style. A quick search for</span></div>
<div style="position:absolute;left:5.00px;top:720.75px" class="cls_004"><span class="cls_004">'</span><span class="cls_007">BaseButtonStyle</span><span class="cls_004">' through the solution files in Visual Studio will locate the source of the</span></div>
<div style="position:absolute;left:5.00px;top:738.75px" class="cls_004"><span class="cls_004">problem. In this case, our problem lay in the </span><span class="cls_007">Application.Resources</span><span class="cls_004"> section of the</span></div>
<div style="position:absolute;left:5.00px;top:756.75px" class="cls_007"><span class="cls_007">App.xaml</span><span class="cls_004"> file. Let's take a closer look:</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:44110px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background057.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:9.00px" class="cls_007"><span class="cls_007"><Style x:Key="SmallButtonStyle" TargetType="{x:Type Button}"</span></div>
<div style="position:absolute;left:67.97px;top:22.50px" class="cls_007"><span class="cls_007">BasedOn="{StaticResourceBaseButtonStyle}"></span></div>
<div style="position:absolute;left:67.97px;top:36.00px" class="cls_007"><span class="cls_007"><Setter Property="Height" Value="24" /></span></div>
<div style="position:absolute;left:67.97px;top:49.50px" class="cls_007"><span class="cls_007"><Setter Property="Width" Value="24" /></span></div>
<div style="position:absolute;left:52.98px;top:63.00px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:5.00px;top:83.25px" class="cls_004"><span class="cls_004">Here we can see a style that is based on another style, but the base style is apparently</span></div>
<div style="position:absolute;left:5.00px;top:101.25px" class="cls_004"><span class="cls_004">missing. It is this missing base style that is the </span><span class="cls_007">StaticResource</span><span class="cls_004"> named </span><span class="cls_007">BaseButtonStyle</span></div>
<div style="position:absolute;left:5.00px;top:119.25px" class="cls_004"><span class="cls_004">that caused this error. We can fix this problem easily by either creating the referenced base</span></div>
<div style="position:absolute;left:5.00px;top:137.25px" class="cls_004"><span class="cls_004">style in the </span><span class="cls_007">App.xml</span><span class="cls_004"> file, or by removing the </span><span class="cls_007">BasedOn</span><span class="cls_004"> property from the </span><span class="cls_007">SmallButtonStyle</span></div>
<div style="position:absolute;left:5.00px;top:155.25px" class="cls_004"><span class="cls_004">style.</span></div>
<div style="position:absolute;left:5.00px;top:173.25px" class="cls_004"><span class="cls_004">We should always bear in mind that errors like these will most likely reside in the code that</span></div>
<div style="position:absolute;left:5.00px;top:191.25px" class="cls_004"><span class="cls_004">we have just been editing, so that also helps us to narrow down the search. It is therefore</span></div>
<div style="position:absolute;left:5.00px;top:209.25px" class="cls_004"><span class="cls_004">beneficial to run the application often when implementing XAML that may contain errors, as</span></div>
<div style="position:absolute;left:5.00px;top:227.25px" class="cls_004"><span class="cls_004">the more code we write between checking our progress, the more code we need to look</span></div>
<div style="position:absolute;left:5.00px;top:245.25px" class="cls_004"><span class="cls_004">through to find the problem.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:44912px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background058.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_008"><span class="cls_008">Debugging data bound values</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">So far, we have seen that we can utilize a number of sources of information to help with</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">tracking down the causes of our problems. However, what about actual debugging? In other</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">GUI languages, we can add breakpoints at various locations in our code and watch our</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">values changing as we step through our code. While we can also do this with WPF</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">applications, it is not always so obvious where to put our breakpoints to ensure that</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">program execution will hit them.</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">If you remember from the previous chapter, the </span><span class="cls_007">CommandManager.RequerySuggested</span><span class="cls_004"> event is</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">raised when the </span><span class="cls_007">CommandManager</span><span class="cls_004"> detects a change in the UI that could reflect on whether a</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">command could execute or not. Well, it turns out that two of the conditions that the</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_007"><span class="cls_007">CommandManager</span><span class="cls_004"> looks out for is when the application window is either activated or</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">deactivated and we can take advantage of this to help us when debugging. Note that the</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">application window is deactivated when the user moves focus from it and is reactivated</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">when the user returns focus to it.</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">Therefore, while running the application side by side with Visual Studio, we can put a</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">breakpoint in any method that is being used as a </span><span class="cls_007">canExecute</span><span class="cls_004"> handler for our </span><span class="cls_007">ActionCommand</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">class, thereby removing focus from the application. Now, when we click back on the WPF</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_004"><span class="cls_004">application, the focus will be returned to it.</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_004"><span class="cls_004">This will cause the </span><span class="cls_007">CommandManager.RequerySuggested</span><span class="cls_004"> event to be raised and as a result,</span></div>
<div style="position:absolute;left:5.00px;top:363.75px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">canExecute</span><span class="cls_004"> handler will be called and our breakpoint will be hit. This basically means</span></div>
<div style="position:absolute;left:5.00px;top:381.75px" class="cls_004"><span class="cls_004">that we are able to get the program execution into our View Models to debug parameter</span></div>
<div style="position:absolute;left:5.00px;top:399.75px" class="cls_004"><span class="cls_004">values any and every time that we need to. Let's see what else we can do to help fix our</span></div>
<div style="position:absolute;left:5.00px;top:417.75px" class="cls_004"><span class="cls_004">data binding errors.</span></div>
<div style="position:absolute;left:5.00px;top:435.01px" class="cls_011"><span class="cls_011">Outputting values to UI controls</span></div>
<div style="position:absolute;left:5.00px;top:465.00px" class="cls_004"><span class="cls_004">One of the simplest ways of working out what values our data bound properties have is to</span></div>
<div style="position:absolute;left:5.00px;top:483.00px" class="cls_004"><span class="cls_004">just data bind them to other UI controls that have a textual output. For example, if we have</span></div>
<div style="position:absolute;left:5.00px;top:501.00px" class="cls_004"><span class="cls_004">a collection of items and we want to do something with the selected item, but whatever that</span></div>
<div style="position:absolute;left:5.00px;top:519.00px" class="cls_004"><span class="cls_004">is isn't working, we need to verify that our binding to that selected item is correct.</span></div>
<div style="position:absolute;left:5.00px;top:537.00px" class="cls_004"><span class="cls_004">To visualize the result of the binding, we can simply copy and paste the binding path to the</span></div>
<div style="position:absolute;left:5.00px;top:555.00px" class="cls_007"><span class="cls_007">Text</span><span class="cls_004"> property of a </span><span class="cls_007">TextBox</span><span class="cls_004"> and run the application. If our binding path is correct, we'll see</span></div>
<div style="position:absolute;left:5.00px;top:573.00px" class="cls_004"><span class="cls_004">something output in the </span><span class="cls_007">TextBox</span><span class="cls_004"> and if not, we'll know that the problem that we're having is</span></div>
<div style="position:absolute;left:5.00px;top:591.00px" class="cls_004"><span class="cls_004">in fact, down to the binding path. We can therefore use this method to verify that objects</span></div>
<div style="position:absolute;left:5.00px;top:609.00px" class="cls_004"><span class="cls_004">that don't normally have a textual output are at least correctly data bound or not.</span></div>
<div style="position:absolute;left:5.00px;top:627.00px" class="cls_004"><span class="cls_004">This simple technique can help in any situation where the faulty data binding is not already</span></div>
<div style="position:absolute;left:5.00px;top:645.00px" class="cls_004"><span class="cls_004">rendered in a text-based UI control. For example, we might need to debug a data bound</span></div>
<div style="position:absolute;left:5.00px;top:663.00px" class="cls_004"><span class="cls_004">value because a particular visual effect that is created with a </span><span class="cls_007">DataTrigger</span><span class="cls_004"> is not working</span></div>
<div style="position:absolute;left:5.00px;top:681.00px" class="cls_004"><span class="cls_004">and we need to determine whether the problem is related to the UI control or the data</span></div>
<div style="position:absolute;left:5.00px;top:699.00px" class="cls_004"><span class="cls_004">binding path.</span></div>
<div style="position:absolute;left:5.00px;top:716.26px" class="cls_011"><span class="cls_011">Catching changing Dependency Property values</span></div>
<div style="position:absolute;left:5.00px;top:746.25px" class="cls_004"><span class="cls_004">As we saw at the beginning of this chapter, the WPF Framework won't call the CLR</span></div>
<div style="position:absolute;left:5.00px;top:764.25px" class="cls_004"><span class="cls_004">property wrappers of our Dependency Properties when the property values are changing.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:45714px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background059.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">However, there is a way to accomplish this using callback handlers. In fact, we've already</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">seen an example of this when we were looking at the creation of the </span><span class="cls_007">OnEnterKeyDown</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">Attached Property. Let's remind ourselves what that looked like:</span></div>
<div style="position:absolute;left:52.98px;top:63.00px" class="cls_007"><span class="cls_007">public static DependencyProperty OnEnterKeyDownProperty =</span></div>
<div style="position:absolute;left:67.97px;top:76.50px" class="cls_007"><span class="cls_007">DependencyProperty.RegisterAttached("OnEnterKeyDown",</span></div>
<div style="position:absolute;left:67.97px;top:90.00px" class="cls_007"><span class="cls_007">typeof(ICommand), typeof(TextBoxProperties),</span></div>
<div style="position:absolute;left:67.97px;top:103.50px" class="cls_007"><span class="cls_007">new PropertyMetadata(OnOnEnterKeyDownChanged));</span></div>
<div style="position:absolute;left:52.98px;top:157.50px" class="cls_007"><span class="cls_007">public static void OnOnEnterKeyDownChanged(</span></div>
<div style="position:absolute;left:67.97px;top:171.00px" class="cls_007"><span class="cls_007">DependencyObject dependencyObject,</span></div>
<div style="position:absolute;left:52.98px;top:184.50px" class="cls_007"><span class="cls_007">DependencyPropertyChangedEventArgs e)</span></div>
<div style="position:absolute;left:52.98px;top:198.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:211.50px" class="cls_007"><span class="cls_007">TextBox textBox = (TextBox)dependencyObject;</span></div>
<div style="position:absolute;left:67.97px;top:225.00px" class="cls_007"><span class="cls_007">if (e.OldValue == null && e.NewValue != null)</span></div>
<div style="position:absolute;left:82.97px;top:238.50px" class="cls_007"><span class="cls_007">textBox.PreviewKeyDown += TextBox_OnEnterKeyDown;</span></div>
<div style="position:absolute;left:67.97px;top:252.00px" class="cls_007"><span class="cls_007">else if (e.OldValue != null && e.NewValue == null)</span></div>
<div style="position:absolute;left:82.97px;top:265.50px" class="cls_007"><span class="cls_007">textBox.PreviewKeyDown -= TextBox_OnEnterKeyDown;</span></div>
<div style="position:absolute;left:52.98px;top:279.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:299.25px" class="cls_004"><span class="cls_004">For this Attached Property, we used a particular overload of the</span></div>
<div style="position:absolute;left:5.00px;top:317.25px" class="cls_007"><span class="cls_007">DependencyProperty.RegisterAttached</span><span class="cls_004"> method that accepts a </span><span class="cls_007">PropertyMetadata</span><span class="cls_004"> object,</span></div>
<div style="position:absolute;left:5.00px;top:335.25px" class="cls_004"><span class="cls_004">which enabled us to assign a </span><span class="cls_007">PropertyChangedCallback</span><span class="cls_004"> handler to the property. Note that</span></div>
<div style="position:absolute;left:5.00px;top:353.25px" class="cls_004"><span class="cls_004">there is an identical overload for the </span><span class="cls_007">DependencyProperty.Register</span><span class="cls_004"> method for declaring</span></div>
<div style="position:absolute;left:5.00px;top:371.25px" class="cls_004"><span class="cls_004">Dependency Properties.</span></div>
<div style="position:absolute;left:5.00px;top:389.25px" class="cls_004"><span class="cls_004">Program execution will enter these </span><span class="cls_007">PropertyChangedCallback</span><span class="cls_004"> handlers each time their</span></div>
<div style="position:absolute;left:5.00px;top:407.25px" class="cls_004"><span class="cls_004">related Dependency Property changes and so that makes them perfect for debugging their</span></div>
<div style="position:absolute;left:5.00px;top:425.25px" class="cls_004"><span class="cls_004">values. While we don't often need to attach these handlers, it only takes a moment to add</span></div>
<div style="position:absolute;left:5.00px;top:443.25px" class="cls_004"><span class="cls_004">one when we need to and they enable us to find out what's going on with the Dependency</span></div>
<div style="position:absolute;left:5.00px;top:461.25px" class="cls_004"><span class="cls_004">Property values at runtime.</span></div>
<div style="position:absolute;left:5.00px;top:478.51px" class="cls_011"><span class="cls_011">Exploiting converters</span></div>
<div style="position:absolute;left:5.00px;top:508.50px" class="cls_004"><span class="cls_004">If we're having a problem with a data binding that uses an </span><span class="cls_007">IValueConverter</span><span class="cls_004"> to convert the</span></div>
<div style="position:absolute;left:5.00px;top:526.50px" class="cls_004"><span class="cls_004">data bound value from one type to another, then we can place a breakpoint into the </span><span class="cls_007">Convert</span></div>
<div style="position:absolute;left:5.00px;top:544.50px" class="cls_004"><span class="cls_004">method of the converter. As long as we have correctly set up the converter, we can be sure</span></div>
<div style="position:absolute;left:5.00px;top:562.50px" class="cls_004"><span class="cls_004">that the breakpoint will be hit when the binding is evaluated at runtime. If it doesn't get hit,</span></div>
<div style="position:absolute;left:5.00px;top:580.50px" class="cls_004"><span class="cls_004">that will mean that we have not set it up correctly.</span></div>
<div style="position:absolute;left:5.00px;top:598.50px" class="cls_004"><span class="cls_004">However, even when we are not already using a converter on a binding that is not displaying</span></div>
<div style="position:absolute;left:5.00px;top:616.50px" class="cls_004"><span class="cls_004">the value that we are expecting, we can still add one just for this purpose. We can either</span></div>
<div style="position:absolute;left:5.00px;top:634.50px" class="cls_004"><span class="cls_004">add an existing converter to the binding, if we have one of the relevant type, or we can</span></div>
<div style="position:absolute;left:5.00px;top:652.50px" class="cls_004"><span class="cls_004">create a simple converter specifically for the purpose of debugging and use that instead.</span></div>
<div style="position:absolute;left:5.00px;top:670.50px" class="cls_004"><span class="cls_004">Let's take a look at how we might do this.</span></div>
<div style="position:absolute;left:52.98px;top:693.75px" class="cls_007"><span class="cls_007">[ValueConversion(typeof(object), typeof(object))]</span></div>
<div style="position:absolute;left:52.98px;top:707.25px" class="cls_007"><span class="cls_007">public class DataBindingDebugConverter : IValueConverter</span></div>
<div style="position:absolute;left:52.98px;top:720.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:734.25px" class="cls_007"><span class="cls_007">public object Convert(object value, Type targetType, object</span></div>
<div style="position:absolute;left:52.98px;top:747.75px" class="cls_007"><span class="cls_007">parameter,</span></div>
<div style="position:absolute;left:82.97px;top:761.25px" class="cls_007"><span class="cls_007">CultureInfo culture)</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:46516px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background060.jpg" width=612 height=792></div>
<div style="position:absolute;left:67.97px;top:3.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:16.50px" class="cls_007"><span class="cls_007">if (Debugger.IsAttached) Debugger.Break();</span></div>
<div style="position:absolute;left:82.97px;top:30.00px" class="cls_007"><span class="cls_007">return value;</span></div>
<div style="position:absolute;left:67.97px;top:43.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:70.50px" class="cls_007"><span class="cls_007">public object ConvertBack(object value, Type targetType,</span></div>
<div style="position:absolute;left:82.97px;top:84.00px" class="cls_007"><span class="cls_007">object parameter, CultureInfo culture)</span></div>
<div style="position:absolute;left:67.97px;top:97.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:111.00px" class="cls_007"><span class="cls_007">if (Debugger.IsAttached) Debugger.Break();</span></div>
<div style="position:absolute;left:82.97px;top:124.50px" class="cls_007"><span class="cls_007">return value;</span></div>
<div style="position:absolute;left:67.97px;top:138.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:151.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:171.75px" class="cls_004"><span class="cls_004">As you can see from the preceding code snippet, it's a very simple implementation of the</span></div>
<div style="position:absolute;left:5.00px;top:189.75px" class="cls_007"><span class="cls_007">IValueConverter</span><span class="cls_004"> interface. We start by specifying that we are converting from </span><span class="cls_007">object</span><span class="cls_004"> to</span></div>
<div style="position:absolute;left:5.00px;top:207.75px" class="cls_007"><span class="cls_007">object</span><span class="cls_004"> in the </span><span class="cls_007">ValueConversion</span><span class="cls_004"> attribute, thereby outlining that we are not actually</span></div>
<div style="position:absolute;left:5.00px;top:225.75px" class="cls_004"><span class="cls_004">converting any data bound values in this converter. The rest of the class represents a</span></div>
<div style="position:absolute;left:5.00px;top:243.75px" class="cls_004"><span class="cls_004">typical converter class, but without any conversion code.</span></div>
<div style="position:absolute;left:5.00px;top:261.75px" class="cls_004"><span class="cls_004">The only real point of interest here are the two calls to the </span><span class="cls_007">Debugger.Break</span><span class="cls_004"> method from the</span></div>
<div style="position:absolute;left:5.00px;top:279.75px" class="cls_007"><span class="cls_007">System.Diagnostics</span><span class="cls_004"> assembly. When the program execution reaches either of these</span></div>
<div style="position:absolute;left:5.00px;top:297.75px" class="cls_004"><span class="cls_004">method calls, it will automatically break, just as if there were breakpoints set on these lines.</span></div>
<div style="position:absolute;left:5.00px;top:315.75px" class="cls_004"><span class="cls_004">Therefore, when using this converter, we don't even need to set a breakpoint; we can just</span></div>
<div style="position:absolute;left:5.00px;top:333.75px" class="cls_004"><span class="cls_004">plug it into the binding, run the program and investigate the value of the </span><span class="cls_007">value</span><span class="cls_004"> input</span></div>
<div style="position:absolute;left:5.00px;top:351.75px" class="cls_004"><span class="cls_004">parameter. Note the use of the </span><span class="cls_007">Debugger.IsAttached</span><span class="cls_004"> property in the </span><span class="cls_007">if</span><span class="cls_004"> statements, which</span></div>
<div style="position:absolute;left:5.00px;top:369.75px" class="cls_004"><span class="cls_004">are used to ensure that execution will not break in a production environment if this converter</span></div>
<div style="position:absolute;left:5.00px;top:387.75px" class="cls_004"><span class="cls_004">is accidentally left connected. It can be attached like any other converter.</span></div>
<div style="position:absolute;left:52.98px;top:411.00px" class="cls_007"><span class="cls_007">xmlns:Converters="clr-</span></div>
<div style="position:absolute;left:52.98px;top:424.50px" class="cls_007"><span class="cls_007">namespace:CompanyName.ApplicationName.Converters;</span></div>
<div style="position:absolute;left:67.97px;top:438.00px" class="cls_007"><span class="cls_007">assembly=CompanyName.ApplicationName.Converters"</span></div>
<div style="position:absolute;left:52.98px;top:465.00px" class="cls_007"><span class="cls_007"><UserControl.Resources></span></div>
<div style="position:absolute;left:67.97px;top:478.50px" class="cls_007"><span class="cls_007"><Converters:DataBindingDebugConverter x:Key="Debug" /></span></div>
<div style="position:absolute;left:52.98px;top:492.00px" class="cls_007"><span class="cls_007"></UserControl.Resources></span></div>
<div style="position:absolute;left:52.98px;top:519.00px" class="cls_007"><span class="cls_007"><ListBox ItemsSource="{Binding Items, Converter={StaticResource</span></div>
<div style="position:absolute;left:52.98px;top:532.50px" class="cls_007"><span class="cls_007">Debug}}" /></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:47318px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background061.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_008"><span class="cls_008">Summary</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">In this chapter, we've investigated the best ways to track down our coding problems. We've</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">looked at the various debug tracing outputs that we have access to and even discovered</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">how to output our own custom trace information. We discovered that the exceptions that</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">are thrown in WPF often hide their useful information in their </span><span class="cls_007">InnerException</span><span class="cls_004"> properties.</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">Finally, we found out a number of tips and tricks to use when trying to find errors with our</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">data bound values.</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">The next chapter delves deeply into the subject of application frameworks and we get</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">started on constructing our own. We find out about the benefit of base classes and discover</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">alternative ways to implement our framework functionality. The chapter will finish off by</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">investigating a variety of techniques to ensure that our applications maintain the essential</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">Separation of Concerns that MVVM provides.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:48120px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background062.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_002"><span class="cls_002">Chapter 3. Writing Custom Application</span></div>
<div style="position:absolute;left:5.00px;top:39.01px" class="cls_002"><span class="cls_002">Frameworks</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">In this chapter, we will investigate application frameworks and the benefits that they can</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">bring us. We find out the differences between providing this functionality via base classes</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">and interfaces and also discover other ways to build the functionality into our frameworks.</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">The chapter will finish off by investigating a variety of techniques to ensure that our</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">applications maintain the essential Separation of Concerns that MVVM provides.</span></div>
<div style="position:absolute;left:5.00px;top:165.01px" class="cls_008"><span class="cls_008">What is an application framework?</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">In the simplest terms, an application framework is comprised of a library of classes that</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">together, provide the most common functionality required by an application. By using an</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">application framework, we can vastly reduce the amount of work and time that is required</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">to create the various parts of the application. In short, they support the future development</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">of the application.</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">In typical three-tier applications, the framework often extends through all layers of the</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">application; the Presentation Layer, the Business Layer, and the Data Access Layer. In a</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_004"><span class="cls_004">WPF application using the MVVM pattern, we can therefore see aspects of the application</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_004"><span class="cls_004">framework in all three components of the pattern; the Models, the View Models, and the</span></div>
<div style="position:absolute;left:5.00px;top:363.75px" class="cls_004"><span class="cls_004">Views.</span></div>
<div style="position:absolute;left:5.00px;top:381.75px" class="cls_004"><span class="cls_004">Apart from the obvious benefits of the reduced production times and effort involved in</span></div>
<div style="position:absolute;left:5.00px;top:399.75px" class="cls_004"><span class="cls_004">creating our application components, application frameworks also provide many additional</span></div>
<div style="position:absolute;left:5.00px;top:417.75px" class="cls_004"><span class="cls_004">benefits. Typical application frameworks promote reusability, which is one of the core aims</span></div>
<div style="position:absolute;left:5.00px;top:435.75px" class="cls_004"><span class="cls_004">of </span><span class="cls_005">Object-Oriented Programming</span><span class="cls_004"> (</span><span class="cls_005">OOP</span><span class="cls_004">). They do this by providing generic interfaces</span></div>
<div style="position:absolute;left:5.00px;top:454.50px" class="cls_004"><span class="cls_004">and/or base classes that can be used to define the various application components.</span></div>
<div style="position:absolute;left:5.00px;top:472.50px" class="cls_004"><span class="cls_004">By reusing these application framework interfaces and base classes, we also instill a sense</span></div>
<div style="position:absolute;left:5.00px;top:490.50px" class="cls_004"><span class="cls_004">of uniformity and consistency throughout the application. Furthermore, as these frameworks</span></div>
<div style="position:absolute;left:5.00px;top:508.50px" class="cls_004"><span class="cls_004">generally provide additional functionality, or services, the developers working on the</span></div>
<div style="position:absolute;left:5.00px;top:526.50px" class="cls_004"><span class="cls_004">application can save further time when requiring this particular functionality.</span></div>
<div style="position:absolute;left:5.00px;top:544.50px" class="cls_004"><span class="cls_004">Concepts like modularity, maintainability, testability, and extensibility can also be realized by</span></div>
<div style="position:absolute;left:5.00px;top:562.50px" class="cls_004"><span class="cls_004">using an application framework. These frameworks often come with the ability to run</span></div>
<div style="position:absolute;left:5.00px;top:580.50px" class="cls_004"><span class="cls_004">individual components independently of each other and this fits WPF and the MVVM pattern</span></div>
<div style="position:absolute;left:5.00px;top:598.50px" class="cls_004"><span class="cls_004">extremely well. Additionally, application frameworks can also supply patterns of</span></div>
<div style="position:absolute;left:5.00px;top:616.50px" class="cls_004"><span class="cls_004">implementation to further simplify the process of constructing new application components.</span></div>
<div style="position:absolute;left:5.00px;top:634.50px" class="cls_004"><span class="cls_004">Different frameworks are created for different technologies and WPF already have a few</span></div>
<div style="position:absolute;left:5.00px;top:652.50px" class="cls_004"><span class="cls_004">publicly available. Some are relatively lightweight, like the </span><span class="cls_005">MVVM Light Toolkit</span><span class="cls_004"> and the</span></div>
<div style="position:absolute;left:5.00px;top:671.25px" class="cls_005"><span class="cls_005">WPF Application Framework</span><span class="cls_004"> (</span><span class="cls_005">WAF</span><span class="cls_004">), while others are more heavyweight, such as</span></div>
<div style="position:absolute;left:5.00px;top:690.00px" class="cls_005"><span class="cls_005">Caliburn.Micro</span><span class="cls_004"> and the now, open source </span><span class="cls_005">Prism</span><span class="cls_004">. While it is likely that you may have used</span></div>
<div style="position:absolute;left:5.00px;top:708.75px" class="cls_004"><span class="cls_004">one or more of these frameworks at work, instead of investigating these in this chapter,</span></div>
<div style="position:absolute;left:5.00px;top:726.75px" class="cls_004"><span class="cls_004">we'll look at how to create our own lightweight custom framework, that will implement just</span></div>
<div style="position:absolute;left:5.00px;top:744.75px" class="cls_004"><span class="cls_004">the features that we need.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:48922px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background063.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_008"><span class="cls_008">Encapsulating common functionality</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">Probably the most commonly used interface in any WPF application would be the</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_007"><span class="cls_007">INotifyPropertyChanged</span><span class="cls_004"> interface, as it is required to correctly implement data binding. By</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">providing an implementation of this interface in our base class, we can avoid having to</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">repeatedly implement it in every single View Model class. It is therefore, a great candidate</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">for inclusion in our base class. There are a number of different ways to implement it</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">depending on our requirements, so let's take a look at the most basic first:</span></div>
<div style="position:absolute;left:52.98px;top:153.00px" class="cls_007"><span class="cls_007">public virtual event PropertyChangedEventHandler PropertyChanged;</span></div>
<div style="position:absolute;left:52.98px;top:180.00px" class="cls_007"><span class="cls_007">protected virtual void NotifyPropertyChanged(string propertyName)</span></div>
<div style="position:absolute;left:52.98px;top:193.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:207.00px" class="cls_007"><span class="cls_007">if (PropertyChanged != null)</span></div>
<div style="position:absolute;left:82.97px;top:220.50px" class="cls_007"><span class="cls_007">PropertyChanged(this, new</span></div>
<div style="position:absolute;left:52.98px;top:234.00px" class="cls_007"><span class="cls_007">PropertyChangedEventArgs(propertyName));</span></div>
<div style="position:absolute;left:52.98px;top:247.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:267.75px" class="cls_004"><span class="cls_004">In all forms of this implementation, we first need to declare the </span><span class="cls_007">PropertyChanged</span><span class="cls_004"> event. This</span></div>
<div style="position:absolute;left:5.00px;top:285.75px" class="cls_004"><span class="cls_004">is the event that will be used to notify the various binding sources and targets of changes to</span></div>
<div style="position:absolute;left:5.00px;top:303.75px" class="cls_004"><span class="cls_004">the data bound values in our application. Note that this is the only requirement of the</span></div>
<div style="position:absolute;left:5.00px;top:321.75px" class="cls_007"><span class="cls_007">INotifyPropertyChanged</span><span class="cls_004"> interface. There is no </span><span class="cls_007">NotifyPropertyChanged</span><span class="cls_004"> method that we</span></div>
<div style="position:absolute;left:5.00px;top:339.75px" class="cls_004"><span class="cls_004">have to implement, so you may well come across differently named methods that perform</span></div>
<div style="position:absolute;left:5.00px;top:357.75px" class="cls_004"><span class="cls_004">the same functionality.</span></div>
<div style="position:absolute;left:5.00px;top:375.75px" class="cls_004"><span class="cls_004">Of course, without the method, just implementing the event would do nothing. The basic</span></div>
<div style="position:absolute;left:5.00px;top:393.75px" class="cls_004"><span class="cls_004">idea of this method is that as usual, we first check for </span><span class="cls_007">null</span><span class="cls_004">, and then raise the event,</span></div>
<div style="position:absolute;left:5.00px;top:411.75px" class="cls_004"><span class="cls_004">passing the raising class instance as the </span><span class="cls_007">sender</span><span class="cls_004"> parameter and the name of the property</span></div>
<div style="position:absolute;left:5.00px;top:429.75px" class="cls_004"><span class="cls_004">that changed in the </span><span class="cls_007">PropertyChangedEventArgs</span><span class="cls_004">. We have already seen that the null</span></div>
<div style="position:absolute;left:5.00px;top:447.75px" class="cls_004"><span class="cls_004">conditional operator in C# 6.0 provides us with a shorthand notation for this.</span></div>
<div style="position:absolute;left:52.98px;top:471.00px" class="cls_007"><span class="cls_007">PropertyChanged?.Invoke(this, new</span></div>
<div style="position:absolute;left:52.98px;top:484.50px" class="cls_007"><span class="cls_007">PropertyChangedEventArgs(propertyName));</span></div>
<div style="position:absolute;left:5.00px;top:504.75px" class="cls_004"><span class="cls_004">Note that the declared access modifier on this method is </span><span class="cls_007">protected</span><span class="cls_004">, to ensure that all View</span></div>
<div style="position:absolute;left:5.00px;top:522.75px" class="cls_004"><span class="cls_004">Models that derive from this base class will have access to it, while non-deriving classes will</span></div>
<div style="position:absolute;left:5.00px;top:540.75px" class="cls_004"><span class="cls_004">not. Furthermore, the method is also marked as </span><span class="cls_007">virtual</span><span class="cls_004">, so that the derived classes can</span></div>
<div style="position:absolute;left:5.00px;top:558.75px" class="cls_004"><span class="cls_004">override this functionality if required. In the View Models, this method would be called from</span></div>
<div style="position:absolute;left:5.00px;top:576.75px" class="cls_004"><span class="cls_004">a property like this:</span></div>
<div style="position:absolute;left:52.98px;top:600.00px" class="cls_007"><span class="cls_007">private string name = string.Empty;</span></div>
<div style="position:absolute;left:52.98px;top:627.00px" class="cls_007"><span class="cls_007">public string Name</span></div>
<div style="position:absolute;left:52.98px;top:640.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:654.00px" class="cls_007"><span class="cls_007">get { return name; }</span></div>
<div style="position:absolute;left:67.97px;top:667.50px" class="cls_007"><span class="cls_007">set</span></div>
<div style="position:absolute;left:67.97px;top:681.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:694.50px" class="cls_007"><span class="cls_007">if (name != value)</span></div>
<div style="position:absolute;left:82.97px;top:708.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:721.50px" class="cls_007"><span class="cls_007">name = value;</span></div>
<div style="position:absolute;left:97.96px;top:735.00px" class="cls_007"><span class="cls_007">NotifyPropertyChanged("Name");</span></div>
<div style="position:absolute;left:82.97px;top:748.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:762.00px" class="cls_007"><span class="cls_007">}</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:49724px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background064.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:3.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:23.25px" class="cls_004"><span class="cls_004">However, a new attribute was added in .NET 4.5, that gives us a shortcut to use with this</span></div>
<div style="position:absolute;left:5.00px;top:41.25px" class="cls_004"><span class="cls_004">implementation. The </span><span class="cls_007">CallerMemberNameAttribute</span><span class="cls_004"> class enables us to automatically obtain</span></div>
<div style="position:absolute;left:5.00px;top:59.25px" class="cls_004"><span class="cls_004">the name of the method caller, or more specifically in our case, the name of the property</span></div>
<div style="position:absolute;left:5.00px;top:77.25px" class="cls_004"><span class="cls_004">that called the method. We can use it with an optional input parameter with a default value,</span></div>
<div style="position:absolute;left:5.00px;top:95.25px" class="cls_004"><span class="cls_004">like this:</span></div>
<div style="position:absolute;left:52.98px;top:118.50px" class="cls_007"><span class="cls_007">protected virtual void NotifyPropertyChanged(</span></div>
<div style="position:absolute;left:67.97px;top:132.00px" class="cls_007"><span class="cls_007">[CallerMemberName]string propertyName = "")</span></div>
<div style="position:absolute;left:52.98px;top:145.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:159.00px" class="cls_007"><span class="cls_007">PropertyChanged?.Invoke(this,</span></div>
<div style="position:absolute;left:82.97px;top:172.50px" class="cls_007"><span class="cls_007">new PropertyChangedEventArgs(propertyName));</span></div>
<div style="position:absolute;left:52.98px;top:186.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:206.25px" class="cls_004"><span class="cls_004">The calling property can then be simplified to this:</span></div>
<div style="position:absolute;left:52.98px;top:229.50px" class="cls_007"><span class="cls_007">public string Name</span></div>
<div style="position:absolute;left:52.98px;top:243.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:256.50px" class="cls_007"><span class="cls_007">get { return name; }</span></div>
<div style="position:absolute;left:67.97px;top:270.00px" class="cls_007"><span class="cls_007">set { if (name != value) { name = value; NotifyPropertyChanged();</span></div>
<div style="position:absolute;left:52.98px;top:283.50px" class="cls_007"><span class="cls_007">} }</span></div>
<div style="position:absolute;left:52.98px;top:297.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:317.25px" class="cls_004"><span class="cls_004">It's worth noting at this point that in .NET 4.5.3, another improvement to calling the most</span></div>
<div style="position:absolute;left:5.00px;top:335.25px" class="cls_004"><span class="cls_004">basic implementation of this method was introduced. The </span><span class="cls_007">nameof</span><span class="cls_004"> operator also enables us</span></div>
<div style="position:absolute;left:5.00px;top:353.25px" class="cls_004"><span class="cls_004">to avoid using strings to pass the property name, as passing strings can always be error</span></div>
<div style="position:absolute;left:5.00px;top:371.25px" class="cls_004"><span class="cls_004">prone. This new operator basically converts the name of a property to a string at compile-</span></div>
<div style="position:absolute;left:5.00px;top:389.25px" class="cls_004"><span class="cls_004">time, so the end result is exactly the same as passing the string, but less error prone. Using</span></div>
<div style="position:absolute;left:5.00px;top:407.25px" class="cls_004"><span class="cls_004">the preceding property, let's see how this is used:</span></div>
<div style="position:absolute;left:52.98px;top:430.50px" class="cls_007"><span class="cls_007">NotifyPropertyChanged(nameof(Name));</span></div>
<div style="position:absolute;left:5.00px;top:450.75px" class="cls_004"><span class="cls_004">There are also other tricks that we can employ too. For example, we often need to notify</span></div>
<div style="position:absolute;left:5.00px;top:468.75px" class="cls_004"><span class="cls_004">the Framework that more than one property value has changed at once. Visualize a</span></div>
<div style="position:absolute;left:5.00px;top:486.75px" class="cls_004"><span class="cls_004">scenario where we have two properties named </span><span class="cls_007">Price</span><span class="cls_004"> and </span><span class="cls_007">Quantity</span><span class="cls_004"> and a third property</span></div>
<div style="position:absolute;left:5.00px;top:504.75px" class="cls_004"><span class="cls_004">named </span><span class="cls_007">Total</span><span class="cls_004">. As you can imagine, the value of the </span><span class="cls_007">Total</span><span class="cls_004"> property will come from the</span></div>
<div style="position:absolute;left:5.00px;top:522.75px" class="cls_004"><span class="cls_004">calculation of the </span><span class="cls_007">Price</span><span class="cls_004"> value multiplied by the </span><span class="cls_007">Quantity</span><span class="cls_004"> value.</span></div>
<div style="position:absolute;left:52.98px;top:546.00px" class="cls_007"><span class="cls_007">public decimal Total</span></div>
<div style="position:absolute;left:52.98px;top:559.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:573.00px" class="cls_007"><span class="cls_007">get { return Price * Quantity; }</span></div>
<div style="position:absolute;left:52.98px;top:586.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:606.75px" class="cls_004"><span class="cls_004">However, this property has no setter, so where should we call the </span><span class="cls_007">NotifyPropertyChanged</span></div>
<div style="position:absolute;left:5.00px;top:624.75px" class="cls_004"><span class="cls_004">method from? The answer is simple. We need to call it from both of the constituent</span></div>
<div style="position:absolute;left:5.00px;top:642.75px" class="cls_004"><span class="cls_004">property setters, as they can both affect the resulting value of this property.</span></div>
<div style="position:absolute;left:5.00px;top:660.75px" class="cls_004"><span class="cls_004">Traditionally, we would have to call the </span><span class="cls_007">NotifyPropertyChanged</span><span class="cls_004"> method once for each</span></div>
<div style="position:absolute;left:5.00px;top:678.75px" class="cls_004"><span class="cls_004">constituent property and once for the </span><span class="cls_007">Total</span><span class="cls_004"> property. However, it is possible to rewrite our</span></div>
<div style="position:absolute;left:5.00px;top:696.75px" class="cls_004"><span class="cls_004">implementation of this method to enable us to pass multiple property names to it in a single</span></div>
<div style="position:absolute;left:5.00px;top:714.75px" class="cls_004"><span class="cls_004">call. For this, we can make use of the </span><span class="cls_007">params</span><span class="cls_004"> keyword to enable any number of input</span></div>
<div style="position:absolute;left:5.00px;top:732.75px" class="cls_004"><span class="cls_004">parameters.</span></div>
<div style="position:absolute;left:52.98px;top:756.00px" class="cls_007"><span class="cls_007">protected void NotifyPropertyChanged(params string[] propertyNames)</span></div>
<div style="position:absolute;left:52.98px;top:769.50px" class="cls_007"><span class="cls_007">{</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:50526px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background065.jpg" width=612 height=792></div>
<div style="position:absolute;left:67.97px;top:3.00px" class="cls_007"><span class="cls_007">if (PropertyChanged != null)</span></div>
<div style="position:absolute;left:67.97px;top:16.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:30.00px" class="cls_007"><span class="cls_007">foreach (string propertyName in propertyNames)</span></div>
<div style="position:absolute;left:82.97px;top:43.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:57.00px" class="cls_007"><span class="cls_007">PropertyChanged(this, new</span></div>
<div style="position:absolute;left:52.98px;top:70.50px" class="cls_007"><span class="cls_007">PropertyChangedEventArgs(propertyName));</span></div>
<div style="position:absolute;left:82.97px;top:84.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:97.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:111.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:144.00px" class="cls_004"><span class="cls_004">When using the </span><span class="cls_007">params</span><span class="cls_004"> keyword, we need to declare an array type input parameter.</span></div>
<div style="position:absolute;left:5.00px;top:162.00px" class="cls_004"><span class="cls_004">However, this array merely holds the input parameters and we do not need to supply an</span></div>
<div style="position:absolute;left:5.00px;top:180.00px" class="cls_004"><span class="cls_004">array when calling this method. Instead, we provide any number of input parameters of the</span></div>
<div style="position:absolute;left:5.00px;top:198.00px" class="cls_004"><span class="cls_004">same type and they will be implicitly added to the array. Going back to our example, this</span></div>
<div style="position:absolute;left:5.00px;top:216.00px" class="cls_004"><span class="cls_004">enables us to call the method like this:</span></div>
<div style="position:absolute;left:52.98px;top:239.25px" class="cls_007"><span class="cls_007">private decimal price = 0M;</span></div>
<div style="position:absolute;left:52.98px;top:266.25px" class="cls_007"><span class="cls_007">public decimal Price</span></div>
<div style="position:absolute;left:52.98px;top:279.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:293.25px" class="cls_007"><span class="cls_007">get { return price; }</span></div>
<div style="position:absolute;left:67.97px;top:306.75px" class="cls_007"><span class="cls_007">set</span></div>
<div style="position:absolute;left:67.97px;top:320.25px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:333.75px" class="cls_007"><span class="cls_007">if (price != value)</span></div>
<div style="position:absolute;left:82.97px;top:347.25px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:360.75px" class="cls_007"><span class="cls_007">price = value;</span></div>
<div style="position:absolute;left:97.96px;top:374.25px" class="cls_007"><span class="cls_007">NotifyPropertyChanged(nameof(Price), nameof(Total));</span></div>
<div style="position:absolute;left:82.97px;top:387.75px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:401.25px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:414.75px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:435.00px" class="cls_004"><span class="cls_004">We therefore have a variety of different ways to implement this method, depending on what</span></div>
<div style="position:absolute;left:5.00px;top:453.00px" class="cls_004"><span class="cls_004">suits our requirements. We can even add a number of overloads of the method to provide</span></div>
<div style="position:absolute;left:5.00px;top:471.00px" class="cls_004"><span class="cls_004">the users of our framework with more choices. We'll see a further enhancement to this</span></div>
<div style="position:absolute;left:5.00px;top:489.00px" class="cls_004"><span class="cls_004">method later, but for now, let's see what our </span><span class="cls_007">BaseViewModel</span><span class="cls_004"> class might look like so far:</span></div>
<div style="position:absolute;left:52.98px;top:512.25px" class="cls_007"><span class="cls_007">using System.ComponentModel;</span></div>
<div style="position:absolute;left:52.98px;top:539.25px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.ViewModels</span></div>
<div style="position:absolute;left:52.98px;top:552.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:566.25px" class="cls_007"><span class="cls_007">public class BaseViewModel : INotifyPropertyChanged</span></div>
<div style="position:absolute;left:67.97px;top:579.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:593.25px" class="cls_007"><span class="cls_007">#region INotifyPropertyChanged Members</span></div>
<div style="position:absolute;left:82.97px;top:620.25px" class="cls_007"><span class="cls_007">public event PropertyChangedEventHandler PropertyChanged;</span></div>
<div style="position:absolute;left:82.97px;top:647.25px" class="cls_007"><span class="cls_007">protected void NotifyPropertyChanged(params string[]</span></div>
<div style="position:absolute;left:52.98px;top:660.75px" class="cls_007"><span class="cls_007">propertyNames)</span></div>
<div style="position:absolute;left:82.97px;top:674.25px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:687.75px" class="cls_007"><span class="cls_007">if (PropertyChanged != null)</span></div>
<div style="position:absolute;left:97.96px;top:701.25px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:112.96px;top:714.75px" class="cls_007"><span class="cls_007">foreach (string propertyName in propertyNames)</span></div>
<div style="position:absolute;left:112.96px;top:728.25px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:127.95px;top:741.75px" class="cls_007"><span class="cls_007">PropertyChanged(this,</span></div>
<div style="position:absolute;left:142.94px;top:755.25px" class="cls_007"><span class="cls_007">new PropertyChangedEventArgs(propertyName));</span></div>
<div style="position:absolute;left:112.96px;top:768.75px" class="cls_007"><span class="cls_007">}</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:51328px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background066.jpg" width=612 height=792></div>
<div style="position:absolute;left:97.96px;top:3.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:16.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:43.50px" class="cls_007"><span class="cls_007">protected virtual void NotifyPropertyChanged(</span></div>
<div style="position:absolute;left:97.96px;top:57.00px" class="cls_007"><span class="cls_007">[CallerMemberName]string propertyName = "")</span></div>
<div style="position:absolute;left:82.97px;top:70.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:84.00px" class="cls_007"><span class="cls_007">PropertyChanged?.Invoke(this,</span></div>
<div style="position:absolute;left:112.96px;top:97.50px" class="cls_007"><span class="cls_007">new PropertyChangedEventArgs(propertyName));</span></div>
<div style="position:absolute;left:82.97px;top:111.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:138.00px" class="cls_007"><span class="cls_007">#endregion</span></div>
<div style="position:absolute;left:67.97px;top:151.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:165.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:185.25px" class="cls_004"><span class="cls_004">To summarize, we started with an interface that declared a single event. The interface itself</span></div>
<div style="position:absolute;left:5.00px;top:203.25px" class="cls_004"><span class="cls_004">provides no functionality and in fact, we as the implementers have to provide the</span></div>
<div style="position:absolute;left:5.00px;top:221.25px" class="cls_004"><span class="cls_004">functionality, in the form of the </span><span class="cls_007">NotifyPropertyChanged</span><span class="cls_004"> method and the calling of that</span></div>
<div style="position:absolute;left:5.00px;top:239.25px" class="cls_004"><span class="cls_004">method each time a property value changes. But the reward for doing this is that the UI</span></div>
<div style="position:absolute;left:5.00px;top:257.25px" class="cls_004"><span class="cls_004">controls are listening and responding to those events and so by implementing this interface,</span></div>
<div style="position:absolute;left:5.00px;top:275.25px" class="cls_004"><span class="cls_004">we have gained this additional data binding capability.</span></div>
<div style="position:absolute;left:5.00px;top:293.25px" class="cls_004"><span class="cls_004">However, we can provide functionality in our application framework in a number of different</span></div>
<div style="position:absolute;left:5.00px;top:311.25px" class="cls_004"><span class="cls_004">ways. The two main ways are through the use of base classes and interfaces. The main</span></div>
<div style="position:absolute;left:5.00px;top:329.25px" class="cls_004"><span class="cls_004">difference between these two approaches relate to the amount of development that the</span></div>
<div style="position:absolute;left:5.00px;top:347.25px" class="cls_004"><span class="cls_004">users of our framework will have to accomplish in order to create the various application</span></div>
<div style="position:absolute;left:5.00px;top:365.25px" class="cls_004"><span class="cls_004">components.</span></div>
<div style="position:absolute;left:5.00px;top:383.25px" class="cls_004"><span class="cls_004">When we use interfaces, we are basically supplying a contract that the developers will have</span></div>
<div style="position:absolute;left:5.00px;top:401.25px" class="cls_004"><span class="cls_004">to honor, by providing the implementation themselves. However, when we use base</span></div>
<div style="position:absolute;left:5.00px;top:419.25px" class="cls_004"><span class="cls_004">classes, we are able to provide that implementation for them. So generally, base classes</span></div>
<div style="position:absolute;left:5.00px;top:437.25px" class="cls_004"><span class="cls_004">provide ready written functionality, whereas interfaces rely on the developers to provide</span></div>
<div style="position:absolute;left:5.00px;top:455.25px" class="cls_004"><span class="cls_004">some or all of that functionality for themselves.</span></div>
<div style="position:absolute;left:5.00px;top:473.25px" class="cls_004"><span class="cls_004">We've just seen an example of implementing an interface in our View Model base class.</span></div>
<div style="position:absolute;left:5.00px;top:491.25px" class="cls_004"><span class="cls_004">Let's now take a look at what else we can encapsulate in our other framework base</span></div>
<div style="position:absolute;left:5.00px;top:509.25px" class="cls_004"><span class="cls_004">classes and compare the differences between providing features or functionality in base</span></div>
<div style="position:absolute;left:5.00px;top:527.25px" class="cls_004"><span class="cls_004">classes and interfaces. Let's turn our attention to our Data Model classes now.</span></div>
<div style="position:absolute;left:5.00px;top:544.51px" class="cls_011"><span class="cls_011">In base classes</span></div>
<div style="position:absolute;left:5.00px;top:574.50px" class="cls_004"><span class="cls_004">We have seen that in a WPF application, it is essential for us to have an implementation of</span></div>
<div style="position:absolute;left:5.00px;top:592.50px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">INotifyPropertyChanged</span><span class="cls_004"> interface in our View Model base class. Likewise, we will also</span></div>
<div style="position:absolute;left:5.00px;top:610.50px" class="cls_004"><span class="cls_004">need a similar implementation in our Data Model base class. Remember that when Data</span></div>
<div style="position:absolute;left:5.00px;top:628.50px" class="cls_004"><span class="cls_004">Models are mentioned here, we are discussing the business model classes that are</span></div>
<div style="position:absolute;left:5.00px;top:646.50px" class="cls_004"><span class="cls_004">combined with the View Model properties and functionality from the second application</span></div>
<div style="position:absolute;left:5.00px;top:664.50px" class="cls_004"><span class="cls_004">structure example in </span><span class="cls_015">Chapter 1</span><span class="cls_004">, </span><span class="cls_006">A Smarter Way Of Working With WPF</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:683.25px" class="cls_004"><span class="cls_004">All of these </span><span class="cls_007">DataModel</span><span class="cls_004"> classes will need to extend their base class, because they will all</span></div>
<div style="position:absolute;left:5.00px;top:701.25px" class="cls_004"><span class="cls_004">need to have access to its </span><span class="cls_007">INotifyPropertyChanged</span><span class="cls_004"> implementation. As we progress</span></div>
<div style="position:absolute;left:5.00px;top:719.25px" class="cls_004"><span class="cls_004">through the chapters in this book, we will see more and more reasons why we need</span></div>
<div style="position:absolute;left:5.00px;top:737.25px" class="cls_004"><span class="cls_004">separate base classes for our Data Models and View Models. For example, let's imagine</span></div>
<div style="position:absolute;left:5.00px;top:755.25px" class="cls_004"><span class="cls_004">that we want to provide these Data Models with some simple auditing properties and</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:52130px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background067.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">investigate what our base class might look like:</span></div>
<div style="position:absolute;left:52.98px;top:27.00px" class="cls_007"><span class="cls_007">using System;</span></div>
<div style="position:absolute;left:52.98px;top:54.00px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.DataModels</span></div>
<div style="position:absolute;left:52.98px;top:67.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:81.00px" class="cls_007"><span class="cls_007">public class BaseDataModel : INotifyPropertyChanged</span></div>
<div style="position:absolute;left:67.97px;top:94.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:108.00px" class="cls_007"><span class="cls_007">private DateTime createdOn;</span></div>
<div style="position:absolute;left:82.97px;top:121.50px" class="cls_007"><span class="cls_007">private DateTime? updatedOn;</span></div>
<div style="position:absolute;left:82.97px;top:135.00px" class="cls_007"><span class="cls_007">private User createdBy, updatedBy;</span></div>
<div style="position:absolute;left:82.97px;top:162.00px" class="cls_007"><span class="cls_007">public DateTime CreatedOn</span></div>
<div style="position:absolute;left:82.97px;top:175.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:189.00px" class="cls_007"><span class="cls_007">get { return createdOn; }</span></div>
<div style="position:absolute;left:97.96px;top:202.50px" class="cls_007"><span class="cls_007">set { createdOn = value; NotifyPropertyChanged(); }</span></div>
<div style="position:absolute;left:82.97px;top:216.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:243.00px" class="cls_007"><span class="cls_007">public User CreatedBy</span></div>
<div style="position:absolute;left:82.97px;top:256.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:270.00px" class="cls_007"><span class="cls_007">get { return createdBy; }</span></div>
<div style="position:absolute;left:97.96px;top:283.50px" class="cls_007"><span class="cls_007">set { createdBy = value; NotifyPropertyChanged(); }</span></div>
<div style="position:absolute;left:82.97px;top:297.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:324.00px" class="cls_007"><span class="cls_007">public DateTime? UpdatedOn</span></div>
<div style="position:absolute;left:82.97px;top:337.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:351.00px" class="cls_007"><span class="cls_007">get { return updatedOn; }</span></div>
<div style="position:absolute;left:97.96px;top:364.50px" class="cls_007"><span class="cls_007">set { updatedOn = value; NotifyPropertyChanged(); }</span></div>
<div style="position:absolute;left:82.97px;top:378.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:405.00px" class="cls_007"><span class="cls_007">public User UpdatedBy</span></div>
<div style="position:absolute;left:82.97px;top:418.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:432.00px" class="cls_007"><span class="cls_007">get { return updatedBy; }</span></div>
<div style="position:absolute;left:97.96px;top:445.50px" class="cls_007"><span class="cls_007">set { updatedBy = value; NotifyPropertyChanged(); }</span></div>
<div style="position:absolute;left:82.97px;top:459.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:486.00px" class="cls_007"><span class="cls_007">#region INotifyPropertyChanged Members</span></div>
<div style="position:absolute;left:82.97px;top:540.00px" class="cls_007"><span class="cls_007">#endregion</span></div>
<div style="position:absolute;left:67.97px;top:553.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:567.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:587.25px" class="cls_004"><span class="cls_004">Here we see our auditing properties, along with the hidden </span><span class="cls_007">INotifyPropertyChanged</span></div>
<div style="position:absolute;left:5.00px;top:605.25px" class="cls_004"><span class="cls_004">implementation that we saw earlier. For now, let's keep the implementation the same as</span></div>
<div style="position:absolute;left:5.00px;top:623.25px" class="cls_004"><span class="cls_004">that of the </span><span class="cls_007">BaseViewModel</span><span class="cls_004"> class. Note that using this particular base class would result in all</span></div>
<div style="position:absolute;left:5.00px;top:641.25px" class="cls_004"><span class="cls_004">derived classes getting access to these properties, whether they needed them or not.</span></div>
<div style="position:absolute;left:5.00px;top:659.25px" class="cls_004"><span class="cls_004">We might then decide to declare another base class, so that we can have one that provides</span></div>
<div style="position:absolute;left:5.00px;top:677.25px" class="cls_004"><span class="cls_004">access to our implementation of the </span><span class="cls_007">INotifyPropertyChanged</span><span class="cls_004"> interface and one that</span></div>
<div style="position:absolute;left:5.00px;top:695.25px" class="cls_004"><span class="cls_004">extends that base class and adds the new auditable properties shown earlier. In this way,</span></div>
<div style="position:absolute;left:5.00px;top:713.25px" class="cls_004"><span class="cls_004">all derived classes can make use of the </span><span class="cls_007">INotifyPropertyChanged</span><span class="cls_004"> interface implementation</span></div>
<div style="position:absolute;left:5.00px;top:731.25px" class="cls_004"><span class="cls_004">and the classes that require the auditable properties as well can derive from the second</span></div>
<div style="position:absolute;left:5.00px;top:749.25px" class="cls_004"><span class="cls_004">base class.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:52932px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background068.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:206.25px" class="cls_004"><span class="cls_004">For this basic example, we seem to have solved our problem. If these auditable properties</span></div>
<div style="position:absolute;left:5.00px;top:224.25px" class="cls_004"><span class="cls_004">were the only properties that we wanted to provide to our derived classes, then this would</span></div>
<div style="position:absolute;left:5.00px;top:242.25px" class="cls_004"><span class="cls_004">not be such a bad situation. However, an average a framework will typically provide far</span></div>
<div style="position:absolute;left:5.00px;top:260.25px" class="cls_004"><span class="cls_004">more than this.</span></div>
<div style="position:absolute;left:5.00px;top:278.25px" class="cls_004"><span class="cls_004">Let's now imagine that we wanted to provide some basic undo capability. We'll see an</span></div>
<div style="position:absolute;left:5.00px;top:296.25px" class="cls_004"><span class="cls_004">example of this later in this chapter, but for now we'll keep this simple. Without actually</span></div>
<div style="position:absolute;left:5.00px;top:314.25px" class="cls_004"><span class="cls_004">specifying the required members of this new base class, let's just think about this first.</span></div>
<div style="position:absolute;left:5.00px;top:332.25px" class="cls_004"><span class="cls_004">Now we have a situation where we already have two different base classes and we want to</span></div>
<div style="position:absolute;left:5.00px;top:350.25px" class="cls_004"><span class="cls_004">provide some further functionality. Where should we declare our new properties? We could</span></div>
<div style="position:absolute;left:5.00px;top:368.25px" class="cls_004"><span class="cls_004">derive from either one, or indirectly, from both of the existing base classes, as shown in the</span></div>
<div style="position:absolute;left:5.00px;top:386.25px" class="cls_004"><span class="cls_004">following diagram, in order to create this new "synchronizable" base class.</span></div>
<div style="position:absolute;left:5.00px;top:605.25px" class="cls_004"><span class="cls_004">So now, we could have four different base classes that the developers, that use our</span></div>
<div style="position:absolute;left:5.00px;top:623.25px" class="cls_004"><span class="cls_004">framework, could extend. There could be some confusion as to exactly which base class</span></div>
<div style="position:absolute;left:5.00px;top:641.25px" class="cls_004"><span class="cls_004">they need to extend, but overall, this situation is still just about manageable. However,</span></div>
<div style="position:absolute;left:5.00px;top:659.25px" class="cls_004"><span class="cls_004">imagine if we want to provide some additional properties or functionality in one or more</span></div>
<div style="position:absolute;left:5.00px;top:677.25px" class="cls_004"><span class="cls_004">levels of base class.</span></div>
<div style="position:absolute;left:5.00px;top:695.25px" class="cls_004"><span class="cls_004">In order to enable every combination of functionality from these base classes, we could end</span></div>
<div style="position:absolute;left:5.00px;top:713.25px" class="cls_004"><span class="cls_004">up with as many as eight separate base classes. Each additional level of functionality that</span></div>
<div style="position:absolute;left:5.00px;top:731.25px" class="cls_004"><span class="cls_004">we provide will either double the total number of base classes that we have, or mean that</span></div>
<div style="position:absolute;left:5.00px;top:749.25px" class="cls_004"><span class="cls_004">the developers sometimes have to derive from a base class with functionality or properties</span></div>
<div style="position:absolute;left:5.00px;top:767.25px" class="cls_004"><span class="cls_004">that they do not require. Now that we have uncovered a potential problem of utilizing base</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:53734px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background069.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">classes, let's see if declaring interfaces can help with this situation.</span></div>
<div style="position:absolute;left:5.00px;top:21.01px" class="cls_011"><span class="cls_011">Through interfaces</span></div>
<div style="position:absolute;left:5.00px;top:51.00px" class="cls_004"><span class="cls_004">Going back to our auditing example, we could have declared these properties in an</span></div>
<div style="position:absolute;left:5.00px;top:69.00px" class="cls_004"><span class="cls_004">interface instead. Let's see what that might look like:</span></div>
<div style="position:absolute;left:52.98px;top:92.25px" class="cls_007"><span class="cls_007">using System;</span></div>
<div style="position:absolute;left:52.98px;top:119.25px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.DataModels.Interfaces</span></div>
<div style="position:absolute;left:52.98px;top:132.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:146.25px" class="cls_007"><span class="cls_007">public interface IAuditable</span></div>
<div style="position:absolute;left:67.97px;top:159.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:173.25px" class="cls_007"><span class="cls_007">DateTime CreatedOn { get; set; }</span></div>
<div style="position:absolute;left:82.97px;top:200.25px" class="cls_007"><span class="cls_007">User CreatedBy { get; set; }</span></div>
<div style="position:absolute;left:82.97px;top:227.25px" class="cls_007"><span class="cls_007">DateTime? UpdatedOn { get; set; }</span></div>
<div style="position:absolute;left:82.97px;top:254.25px" class="cls_007"><span class="cls_007">User UpdatedBy { get; set; }</span></div>
<div style="position:absolute;left:67.97px;top:267.75px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:281.25px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:301.50px" class="cls_004"><span class="cls_004">Now, if a developer requires these properties, they can implement this interface as well as</span></div>
<div style="position:absolute;left:5.00px;top:319.50px" class="cls_004"><span class="cls_004">extending the Data Model base class.</span></div>
<div style="position:absolute;left:52.98px;top:544.50px" class="cls_007"><span class="cls_007">using System;</span></div>
<div style="position:absolute;left:52.98px;top:558.00px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.DataModels.Interfaces;</span></div>
<div style="position:absolute;left:52.98px;top:585.00px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.DataModels</span></div>
<div style="position:absolute;left:52.98px;top:598.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:612.00px" class="cls_007"><span class="cls_007">public class Invoice : BaseDataModel, IAuditable</span></div>
<div style="position:absolute;left:67.97px;top:625.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:639.00px" class="cls_007"><span class="cls_007">private DateTime createdOn;</span></div>
<div style="position:absolute;left:82.97px;top:652.50px" class="cls_007"><span class="cls_007">private DateTime? updatedOn;</span></div>
<div style="position:absolute;left:82.97px;top:666.00px" class="cls_007"><span class="cls_007">private User createdBy, updatedBy;</span></div>
<div style="position:absolute;left:82.97px;top:693.00px" class="cls_007"><span class="cls_007">public DateTime CreatedOn</span></div>
<div style="position:absolute;left:82.97px;top:706.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:720.00px" class="cls_007"><span class="cls_007">get { return createdOn; }</span></div>
<div style="position:absolute;left:97.96px;top:733.50px" class="cls_007"><span class="cls_007">set { createdOn = value; NotifyPropertyChanged(); }</span></div>
<div style="position:absolute;left:82.97px;top:747.00px" class="cls_007"><span class="cls_007">}</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:54536px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background070.jpg" width=612 height=792></div>
<div style="position:absolute;left:82.97px;top:3.00px" class="cls_007"><span class="cls_007">public User CreatedBy</span></div>
<div style="position:absolute;left:82.97px;top:16.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:30.00px" class="cls_007"><span class="cls_007">get { return createdBy; }</span></div>
<div style="position:absolute;left:97.96px;top:43.50px" class="cls_007"><span class="cls_007">set { createdBy = value; NotifyPropertyChanged(); }</span></div>
<div style="position:absolute;left:82.97px;top:57.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:84.00px" class="cls_007"><span class="cls_007">public DateTime? UpdatedOn</span></div>
<div style="position:absolute;left:82.97px;top:97.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:111.00px" class="cls_007"><span class="cls_007">get { return updatedOn; }</span></div>
<div style="position:absolute;left:97.96px;top:124.50px" class="cls_007"><span class="cls_007">set { updatedOn = value; NotifyPropertyChanged(); }</span></div>
<div style="position:absolute;left:82.97px;top:138.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:165.00px" class="cls_007"><span class="cls_007">public User UpdatedBy</span></div>
<div style="position:absolute;left:82.97px;top:178.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:192.00px" class="cls_007"><span class="cls_007">get { return updatedBy; }</span></div>
<div style="position:absolute;left:97.96px;top:205.50px" class="cls_007"><span class="cls_007">set { updatedBy = value; NotifyPropertyChanged(); }</span></div>
<div style="position:absolute;left:82.97px;top:219.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:232.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:246.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:266.25px" class="cls_004"><span class="cls_004">Initially then, it seems as though this could be a better way to go, but let's continue to</span></div>
<div style="position:absolute;left:5.00px;top:284.25px" class="cls_004"><span class="cls_004">investigate the same scenario that we looked at with the base classes. Let's now imagine</span></div>
<div style="position:absolute;left:5.00px;top:302.25px" class="cls_004"><span class="cls_004">that we want to provide the same basic undo capability using interfaces. We didn't actually</span></div>
<div style="position:absolute;left:5.00px;top:320.25px" class="cls_004"><span class="cls_004">investigate which members would be required for this, but it will require both properties and</span></div>
<div style="position:absolute;left:5.00px;top:338.25px" class="cls_004"><span class="cls_004">methods.</span></div>
<div style="position:absolute;left:5.00px;top:356.25px" class="cls_004"><span class="cls_004">This is where the interface approach starts to break down somewhat. We can ensure that</span></div>
<div style="position:absolute;left:5.00px;top:374.25px" class="cls_004"><span class="cls_004">implementers of our </span><span class="cls_007">ISynchronization</span><span class="cls_004"> interface have particular properties and methods,</span></div>
<div style="position:absolute;left:5.00px;top:392.25px" class="cls_004"><span class="cls_004">but we have no control over their implementation of those methods. In order to provide the</span></div>
<div style="position:absolute;left:5.00px;top:410.25px" class="cls_004"><span class="cls_004">ability to undo changes, we need to provide the actual implementation of these methods,</span></div>
<div style="position:absolute;left:5.00px;top:428.25px" class="cls_004"><span class="cls_004">rather than just the required scaffolding.</span></div>
<div style="position:absolute;left:5.00px;top:446.25px" class="cls_004"><span class="cls_004">If this was left up to the developers to implement each time they used the interface, they</span></div>
<div style="position:absolute;left:5.00px;top:464.25px" class="cls_004"><span class="cls_004">might not implement it correctly, or perhaps they might implement it differently in different</span></div>
<div style="position:absolute;left:5.00px;top:482.25px" class="cls_004"><span class="cls_004">classes and break the consistency of the application. Therefore, to implement some</span></div>
<div style="position:absolute;left:5.00px;top:500.25px" class="cls_004"><span class="cls_004">functionality, it seems as though we really do need to use some kind of base class.</span></div>
<div style="position:absolute;left:5.00px;top:518.25px" class="cls_004"><span class="cls_004">However, we also have a third option that involves a mix of the two approaches. We could</span></div>
<div style="position:absolute;left:5.00px;top:536.25px" class="cls_004"><span class="cls_004">implement some functionality in a base class, but instead of deriving our Data Model</span></div>
<div style="position:absolute;left:5.00px;top:554.25px" class="cls_004"><span class="cls_004">classes from it, we could add a property of that type, so that we can still access its public</span></div>
<div style="position:absolute;left:5.00px;top:572.25px" class="cls_004"><span class="cls_004">members.</span></div>
<div style="position:absolute;left:5.00px;top:590.25px" class="cls_004"><span class="cls_004">We could then declare an interface that simply has a single property of the type of this new</span></div>
<div style="position:absolute;left:5.00px;top:608.25px" class="cls_004"><span class="cls_004">base class. In this way, we would be free to add the different functionality from different</span></div>
<div style="position:absolute;left:5.00px;top:626.25px" class="cls_004"><span class="cls_004">base classes to just the classes that require them. Let's look at an example of this:</span></div>
<div style="position:absolute;left:52.98px;top:649.50px" class="cls_007"><span class="cls_007">public interface IAuditable</span></div>
<div style="position:absolute;left:52.98px;top:663.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:676.50px" class="cls_007"><span class="cls_007">Auditable Auditable { get; set; }</span></div>
<div style="position:absolute;left:52.98px;top:690.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:710.25px" class="cls_004"><span class="cls_004">This </span><span class="cls_007">Auditable</span><span class="cls_004"> class would have the same properties as those in the previous </span><span class="cls_007">IAuditable</span></div>
<div style="position:absolute;left:5.00px;top:728.25px" class="cls_004"><span class="cls_004">interface shown in the preceding code. The new </span><span class="cls_007">IAuditable</span><span class="cls_004"> interface would be</span></div>
<div style="position:absolute;left:5.00px;top:746.25px" class="cls_004"><span class="cls_004">implemented by the Data Model classes by simply declaring a property of type </span><span class="cls_007">Auditable</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:52.98px;top:769.50px" class="cls_007"><span class="cls_007">public class User : IAuditable</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:55338px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background071.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:3.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:16.50px" class="cls_007"><span class="cls_007">private Auditable auditable;</span></div>
<div style="position:absolute;left:67.97px;top:43.50px" class="cls_007"><span class="cls_007">public Auditable Auditable</span></div>
<div style="position:absolute;left:67.97px;top:57.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:70.50px" class="cls_007"><span class="cls_007">get { return auditable; }</span></div>
<div style="position:absolute;left:82.97px;top:84.00px" class="cls_007"><span class="cls_007">set { auditable = value; }</span></div>
<div style="position:absolute;left:67.97px;top:97.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:138.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:158.25px" class="cls_004"><span class="cls_004">It could be used by the framework, for example, to output the names of each user and</span></div>
<div style="position:absolute;left:5.00px;top:176.25px" class="cls_004"><span class="cls_004">when they were created into a report. In the following example, we use the </span><span class="cls_005">Interpolated</span></div>
<div style="position:absolute;left:5.00px;top:195.00px" class="cls_005"><span class="cls_005">Strings</span><span class="cls_004"> syntax that was introduced in C# 6.0 for constructing our string. It's like the</span></div>
<div style="position:absolute;left:5.00px;top:213.75px" class="cls_007"><span class="cls_007">string.Format</span><span class="cls_004"> method, but with the method call replaced with a </span><span class="cls_007">$</span><span class="cls_004"> sign and the numerical</span></div>
<div style="position:absolute;left:5.00px;top:231.75px" class="cls_004"><span class="cls_004">format items replaced with their related values.</span></div>
<div style="position:absolute;left:52.98px;top:255.00px" class="cls_007"><span class="cls_007">foreach (IAuditable user in Users)</span></div>
<div style="position:absolute;left:52.98px;top:268.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:282.00px" class="cls_007"><span class="cls_007">Report.AddLine($"{user.Name} created on</span></div>
<div style="position:absolute;left:52.98px;top:295.50px" class="cls_007"><span class="cls_007">{user.Auditable.CreatedOn}");</span></div>
<div style="position:absolute;left:52.98px;top:309.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:329.25px" class="cls_004"><span class="cls_004">Most interestingly, as this interface could be implemented by many different types of object,</span></div>
<div style="position:absolute;left:5.00px;top:347.25px" class="cls_004"><span class="cls_004">the preceding code could also be used with objects of different types. Note this slight</span></div>
<div style="position:absolute;left:5.00px;top:365.25px" class="cls_004"><span class="cls_004">difference:</span></div>
<div style="position:absolute;left:52.98px;top:388.50px" class="cls_007"><span class="cls_007">List<IAuditable> auditableObjects = GetAuditableObjects();</span></div>
<div style="position:absolute;left:52.98px;top:402.00px" class="cls_007"><span class="cls_007">foreach (IAuditable user in auditableObjects)</span></div>
<div style="position:absolute;left:52.98px;top:415.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:429.00px" class="cls_007"><span class="cls_007">Report.AddLine($"{user.Name} created on</span></div>
<div style="position:absolute;left:52.98px;top:442.50px" class="cls_007"><span class="cls_007">{user.Auditable.CreatedOn}");</span></div>
<div style="position:absolute;left:52.98px;top:456.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:476.25px" class="cls_004"><span class="cls_004">It's worth pointing out this useful ability to work with objects of different types is not limited</span></div>
<div style="position:absolute;left:5.00px;top:494.25px" class="cls_004"><span class="cls_004">to interfaces. This can also be achieved just as easily with base classes. Imagine a View</span></div>
<div style="position:absolute;left:5.00px;top:512.25px" class="cls_004"><span class="cls_004">that enabled the end user to edit a number of different types of object. We could use this</span></div>
<div style="position:absolute;left:5.00px;top:530.25px" class="cls_004"><span class="cls_004">very similar code to display a confirmation of the changes from each object back to the</span></div>
<div style="position:absolute;left:5.00px;top:548.25px" class="cls_004"><span class="cls_004">user:</span></div>
<div style="position:absolute;left:52.98px;top:571.50px" class="cls_007"><span class="cls_007">List<BaseSynchronizableDataModel> baseDataModels =</span></div>
<div style="position:absolute;left:52.98px;top:585.00px" class="cls_007"><span class="cls_007">GetBaseDataModels();</span></div>
<div style="position:absolute;left:52.98px;top:598.50px" class="cls_007"><span class="cls_007">foreach (BaseSynchronizableDataModel baseDataModel in</span></div>
<div style="position:absolute;left:52.98px;top:612.00px" class="cls_007"><span class="cls_007">baseDataModels)</span></div>
<div style="position:absolute;left:52.98px;top:625.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:639.00px" class="cls_007"><span class="cls_007">if (baseDataModel.HasChanges)</span></div>
<div style="position:absolute;left:82.97px;top:652.50px" class="cls_007"><span class="cls_007">FeedbackManager.Add(baseDataModel.PropertyChanges);</span></div>
<div style="position:absolute;left:52.98px;top:666.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:686.25px" class="cls_004"><span class="cls_004">We have a number of choices when it comes to encapsulating pieces of pre-packaged</span></div>
<div style="position:absolute;left:5.00px;top:704.25px" class="cls_004"><span class="cls_004">functionality into our Data Model classes. Each of these methods that we have investigated</span></div>
<div style="position:absolute;left:5.00px;top:722.25px" class="cls_004"><span class="cls_004">so far have strengths and weaknesses. If we're sure that we want some pre-written</span></div>
<div style="position:absolute;left:5.00px;top:740.25px" class="cls_004"><span class="cls_004">functionality in every one of our Data Model classes, like that of the</span></div>
<div style="position:absolute;left:5.00px;top:758.25px" class="cls_007"><span class="cls_007">INotifyPropertyChanged</span><span class="cls_004"> interface, then we can simply encapsulate it in a base class and</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:56140px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background072.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">derive all of our model classes from that.</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">If we just want our models to have certain properties or methods that can be called from</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">other parts of the framework, but are not concerned with the implementation, then we can</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">use interfaces. If we want some combination of the two ideas, then we can implement a</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">solution using the two methods together. It is up to us to choose the solution that best fits</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">the requirements in hand.</span></div>
<div style="position:absolute;left:5.00px;top:111.01px" class="cls_011"><span class="cls_011">With Extension methods</span></div>
<div style="position:absolute;left:5.00px;top:141.00px" class="cls_004"><span class="cls_004">There is a further method of providing additional functionality to the developers of our</span></div>
<div style="position:absolute;left:5.00px;top:159.00px" class="cls_004"><span class="cls_004">application that was mentioned when investigating the application structures in the </span><span class="cls_015">Chapter</span></div>
<div style="position:absolute;left:5.00px;top:177.00px" class="cls_015"><span class="cls_015">2</span><span class="cls_004">, </span><span class="cls_006">Debugging WPF Applications</span><span class="cls_004">. It is through the use of Extension methods. If you are not</span></div>
<div style="position:absolute;left:5.00px;top:195.75px" class="cls_004"><span class="cls_004">familiar with this amazing .NET feature, Extension methods enable us to write methods that</span></div>
<div style="position:absolute;left:5.00px;top:213.75px" class="cls_004"><span class="cls_004">can be used on objects that we did not create.</span></div>
<div style="position:absolute;left:5.00px;top:231.75px" class="cls_004"><span class="cls_004">At this stage, it's worth pointing out that we don't generally write Extension methods for</span></div>
<div style="position:absolute;left:5.00px;top:249.75px" class="cls_004"><span class="cls_004">classes that we have declared. There are two main reasons for this. The first is that we</span></div>
<div style="position:absolute;left:5.00px;top:267.75px" class="cls_004"><span class="cls_004">created these classes and so we have access to their source code and can therefore</span></div>
<div style="position:absolute;left:5.00px;top:285.75px" class="cls_004"><span class="cls_004">simply declare new methods in these classes directly.</span></div>
<div style="position:absolute;left:5.00px;top:303.75px" class="cls_004"><span class="cls_004">The second reason is that there will be a reference to our </span><span class="cls_007">Extensions</span><span class="cls_004"> project added to</span></div>
<div style="position:absolute;left:5.00px;top:321.75px" class="cls_004"><span class="cls_004">most other projects, including our </span><span class="cls_007">DataModels</span><span class="cls_004"> project, so that they can all take advantage of</span></div>
<div style="position:absolute;left:5.00px;top:339.75px" class="cls_004"><span class="cls_004">the extra capabilities. Therefore, we can't add references to any of our other projects into</span></div>
<div style="position:absolute;left:5.00px;top:357.75px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">Extensions</span><span class="cls_004"> project, because it would create circular dependencies.</span></div>
<div style="position:absolute;left:5.00px;top:375.75px" class="cls_004"><span class="cls_004">You are probably aware of Extension methods already, although perhaps inadvertently, as</span></div>
<div style="position:absolute;left:5.00px;top:393.75px" class="cls_004"><span class="cls_004">most of the LINQ methods are Extension methods. Once declared, they can be used just</span></div>
<div style="position:absolute;left:5.00px;top:411.75px" class="cls_004"><span class="cls_004">like the ordinary methods that were declared within the various classes that we are</span></div>
<div style="position:absolute;left:5.00px;top:429.75px" class="cls_004"><span class="cls_004">extending, although they are differentiated by having different icons in the Visual Studio</span></div>
<div style="position:absolute;left:5.00px;top:447.75px" class="cls_004"><span class="cls_004">IntelliSense display.</span></div>
<div style="position:absolute;left:5.00px;top:540.00px" class="cls_004"><span class="cls_004">The basic principle when declaring them is to have a static class, where each method has</span></div>
<div style="position:absolute;left:5.00px;top:558.00px" class="cls_004"><span class="cls_004">an extra input parameter prefixed with the </span><span class="cls_007">this</span><span class="cls_004"> keyword, that represents the object being</span></div>
<div style="position:absolute;left:5.00px;top:576.00px" class="cls_004"><span class="cls_004">extended. Note that this extra input parameter must be declared first in the parameter list</span></div>
<div style="position:absolute;left:5.00px;top:594.00px" class="cls_004"><span class="cls_004">and that it will not be visible in IntelliSense when calling the method on an instance of an</span></div>
<div style="position:absolute;left:5.00px;top:612.00px" class="cls_004"><span class="cls_004">object.</span></div>
<div style="position:absolute;left:5.00px;top:630.00px" class="cls_004"><span class="cls_004">Extension methods are declared as static methods, but are typically called using instance</span></div>
<div style="position:absolute;left:5.00px;top:648.00px" class="cls_004"><span class="cls_004">method syntax. A simple example should help to clarify this situation. Let's imagine that we</span></div>
<div style="position:absolute;left:5.00px;top:666.00px" class="cls_004"><span class="cls_004">want to be able to call a method on each item in a collection. In fact, we'll see an example</span></div>
<div style="position:absolute;left:5.00px;top:684.00px" class="cls_004"><span class="cls_004">of this being used in our </span><span class="cls_007">BaseSynchronizableCollection</span><span class="cls_004"> class later in this chapter, but now,</span></div>
<div style="position:absolute;left:5.00px;top:702.00px" class="cls_004"><span class="cls_004">let's see how we can do this:</span></div>
<div style="position:absolute;left:52.98px;top:725.25px" class="cls_007"><span class="cls_007">using System;</span></div>
<div style="position:absolute;left:52.98px;top:738.75px" class="cls_007"><span class="cls_007">using System.Collections.Generic;</span></div>
<div style="position:absolute;left:52.98px;top:765.75px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.Extensions</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:56942px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background073.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:3.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:16.50px" class="cls_007"><span class="cls_007">public static class IEnumerableExtensions</span></div>
<div style="position:absolute;left:67.97px;top:30.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:43.50px" class="cls_007"><span class="cls_007">public static void ForEach<T>(this IEnumerable<T> collection,</span></div>
<div style="position:absolute;left:97.96px;top:57.00px" class="cls_007"><span class="cls_007">Action<T> action)</span></div>
<div style="position:absolute;left:82.97px;top:70.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:84.00px" class="cls_007"><span class="cls_007">foreach (T item in collection) action(item);</span></div>
<div style="position:absolute;left:82.97px;top:97.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:111.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:124.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:144.75px" class="cls_004"><span class="cls_004">Here we see the </span><span class="cls_007">this</span><span class="cls_004"> input parameter that specifies the instance of the target type that this</span></div>
<div style="position:absolute;left:5.00px;top:162.75px" class="cls_004"><span class="cls_004">Extension method is called on. Remember that this won't appear in the parameter list in</span></div>
<div style="position:absolute;left:5.00px;top:180.75px" class="cls_004"><span class="cls_004">IntelliSense in Visual Studio, unless it is called through the static class itself, as shown in the</span></div>
<div style="position:absolute;left:5.00px;top:198.75px" class="cls_004"><span class="cls_004">following code.</span></div>
<div style="position:absolute;left:52.98px;top:222.00px" class="cls_007"><span class="cls_007">IEnumerableExtensions.ForEach(collection, i => i.RevertState());</span></div>
<div style="position:absolute;left:5.00px;top:242.25px" class="cls_004"><span class="cls_004">Inside this method, we simply iterate through the collection items, calling the </span><span class="cls_007">Action</span></div>
<div style="position:absolute;left:5.00px;top:260.25px" class="cls_004"><span class="cls_004">specified by the </span><span class="cls_007">action</span><span class="cls_004"> input parameter and passing in each item as the parameter. After</span></div>
<div style="position:absolute;left:5.00px;top:278.25px" class="cls_004"><span class="cls_004">adding a </span><span class="cls_007">using</span><span class="cls_004"> directive to the </span><span class="cls_007">CompanyName.ApplicationName.Extensions</span><span class="cls_004"> namespace,</span></div>
<div style="position:absolute;left:5.00px;top:296.25px" class="cls_004"><span class="cls_004">let's see how this this method is more usually called:</span></div>
<div style="position:absolute;left:52.98px;top:319.50px" class="cls_007"><span class="cls_007">collection.ForEach(i => i.PerformAction());</span></div>
<div style="position:absolute;left:5.00px;top:339.75px" class="cls_004"><span class="cls_004">So you can now see the power of Extension methods and the benefits that they can bring</span></div>
<div style="position:absolute;left:5.00px;top:357.75px" class="cls_004"><span class="cls_004">us. If some functionality that we want is not already provided by a certain class in the .NET</span></div>
<div style="position:absolute;left:5.00px;top:375.75px" class="cls_004"><span class="cls_004">Framework, then we can simply add it in. Take this next example.</span></div>
<div style="position:absolute;left:5.00px;top:393.75px" class="cls_004"><span class="cls_004">Here is an Extension method that has been sorely missed from the existing LINQ Extension</span></div>
<div style="position:absolute;left:5.00px;top:411.75px" class="cls_004"><span class="cls_004">methods. As with the other LINQ methods, this one also works on the </span><span class="cls_007">IEnumerable<T></span></div>
<div style="position:absolute;left:5.00px;top:429.75px" class="cls_004"><span class="cls_004">interface and therefore, also any collection that extends it:</span></div>
<div style="position:absolute;left:52.98px;top:453.00px" class="cls_007"><span class="cls_007">public static IEnumerable<TSource> DistinctBy<TSource, TKey>(</span></div>
<div style="position:absolute;left:67.97px;top:466.50px" class="cls_007"><span class="cls_007">this IEnumerable<TSource> source, Func<TSource, TKey></span></div>
<div style="position:absolute;left:52.98px;top:480.00px" class="cls_007"><span class="cls_007">keySelector)</span></div>
<div style="position:absolute;left:52.98px;top:493.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:507.00px" class="cls_007"><span class="cls_007">HashSet<TKey> keys = new HashSet<TKey>();</span></div>
<div style="position:absolute;left:67.97px;top:520.50px" class="cls_007"><span class="cls_007">foreach (TSource element in source)</span></div>
<div style="position:absolute;left:67.97px;top:534.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:547.50px" class="cls_007"><span class="cls_007">if (keys.Add(keySelector(element))) yield return element;</span></div>
<div style="position:absolute;left:67.97px;top:561.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:574.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:594.75px" class="cls_004"><span class="cls_004">Let's first look at the declaration of this method. We can see that our source collection will</span></div>
<div style="position:absolute;left:5.00px;top:612.75px" class="cls_004"><span class="cls_004">be of type </span><span class="cls_007">TSource</span><span class="cls_004">. Note that this is exactly the same as if the generic type parameter</span></div>
<div style="position:absolute;left:5.00px;top:630.75px" class="cls_004"><span class="cls_004">were named </span><span class="cls_007">T</span><span class="cls_004"> like our other examples, except that this provides a little more detail as to</span></div>
<div style="position:absolute;left:5.00px;top:648.75px" class="cls_004"><span class="cls_004">the use of this type parameter. This naming has come from the</span></div>
<div style="position:absolute;left:5.00px;top:666.75px" class="cls_007"><span class="cls_007">Enumerable.OrderBy<TSource, TKey></span><span class="cls_004"> method, where the </span><span class="cls_007">TSource</span><span class="cls_004"> type parameter</span></div>
<div style="position:absolute;left:5.00px;top:684.75px" class="cls_004"><span class="cls_004">represents our source collection.</span></div>
<div style="position:absolute;left:5.00px;top:702.75px" class="cls_004"><span class="cls_004">Next, we notice that the method name is suffixed by two generic type parameters; first the</span></div>
<div style="position:absolute;left:5.00px;top:720.75px" class="cls_007"><span class="cls_007">TSource</span><span class="cls_004"> parameter and then the </span><span class="cls_007">TKey</span><span class="cls_004"> parameter. This is because we require two generic</span></div>
<div style="position:absolute;left:5.00px;top:738.75px" class="cls_004"><span class="cls_004">type parameters for the input parameter of type </span><span class="cls_007">Func<TSource, TKey></span><span class="cls_004">. If you're not familiar</span></div>
<div style="position:absolute;left:5.00px;top:756.75px" class="cls_004"><span class="cls_004">with the </span><span class="cls_007">Func<T, TResult></span><span class="cls_004"> delegate, as Microsoft call it, it simply encapsulates any method</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:57744px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background074.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">that has a single input parameter of type </span><span class="cls_007">T</span><span class="cls_004"> and returns a value of type </span><span class="cls_007">TResult</span><span class="cls_004">, or in our</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">case, </span><span class="cls_007">TKey</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">"Why are we using this </span><span class="cls_007">Func<T, TResult></span><span class="cls_004"> delegate?", I hear you asking. Well it's simple</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">really. Using this class, we can provide the developers with an object of the same type as</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">those in the source collection and the ability to select a member of that class, in particular,</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">the property that they want to perform the distinct query on. Before looking at the rest of</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">this method, let's see it in use:</span></div>
<div style="position:absolute;left:52.98px;top:135.00px" class="cls_007"><span class="cls_007">IEnumerable<User> distinctUsers = Users.DistinctBy(u =></span></div>
<div style="position:absolute;left:52.98px;top:148.50px" class="cls_007"><span class="cls_007">u.Department);</span></div>
<div style="position:absolute;left:5.00px;top:168.75px" class="cls_004"><span class="cls_004">Let's envisage that we had a </span><span class="cls_007">Department</span><span class="cls_004"> property in our </span><span class="cls_007">User</span><span class="cls_004"> class and a collection of</span></div>
<div style="position:absolute;left:5.00px;top:186.75px" class="cls_004"><span class="cls_004">these users. Now let's imagine that we wanted to find out which departments our users</span></div>
<div style="position:absolute;left:5.00px;top:204.75px" class="cls_004"><span class="cls_004">belonged to. This method would return a single member from each distinct department.</span></div>
<div style="position:absolute;left:5.00px;top:222.75px" class="cls_004"><span class="cls_004">So in this case, we are actually interested in the departments that the users belong to and</span></div>
<div style="position:absolute;left:5.00px;top:240.75px" class="cls_004"><span class="cls_004">not the users themselves. If we wanted to find out the distinct ages of the users, we could</span></div>
<div style="position:absolute;left:5.00px;top:258.75px" class="cls_004"><span class="cls_004">simply use this method again, but specify the </span><span class="cls_007">Age</span><span class="cls_004"> property instead of the </span><span class="cls_007">Department</span></div>
<div style="position:absolute;left:5.00px;top:276.75px" class="cls_004"><span class="cls_004">property.</span></div>
<div style="position:absolute;left:5.00px;top:294.75px" class="cls_004"><span class="cls_004">Referring back to the source code for this method, the </span><span class="cls_007">User</span><span class="cls_004"> class represents the </span><span class="cls_007">TSource</span></div>
<div style="position:absolute;left:5.00px;top:312.75px" class="cls_004"><span class="cls_004">parameter and this is shown in the Lambda expression in the example as the </span><span class="cls_007">u</span><span class="cls_004"> input</span></div>
<div style="position:absolute;left:5.00px;top:330.75px" class="cls_004"><span class="cls_004">parameter. The </span><span class="cls_007">TKey</span><span class="cls_004"> parameter is determined by the type of the class member that is</span></div>
<div style="position:absolute;left:5.00px;top:348.75px" class="cls_004"><span class="cls_004">selected by the developer. In this case, by the string </span><span class="cls_007">Department</span><span class="cls_004"> value. This example could</span></div>
<div style="position:absolute;left:5.00px;top:366.75px" class="cls_004"><span class="cls_004">be written slightly differently to make it clearer:</span></div>
<div style="position:absolute;left:52.98px;top:390.00px" class="cls_007"><span class="cls_007">distinctUsers = Users.DistinctBy((User user) => user.Department);</span></div>
<div style="position:absolute;left:5.00px;top:410.25px" class="cls_004"><span class="cls_004">So our </span><span class="cls_007">Func<TSource, TKey></span><span class="cls_004"> can be seen here, with a </span><span class="cls_007">User</span><span class="cls_004"> input parameter and a string</span></div>
<div style="position:absolute;left:5.00px;top:428.25px" class="cls_004"><span class="cls_004">return value. Now let's focus on the magic of our method. We see a </span><span class="cls_007">HashSet</span><span class="cls_004"> of type string</span></div>
<div style="position:absolute;left:5.00px;top:446.25px" class="cls_004"><span class="cls_004">in our case, being initialized. This type of collection is essential to this method as it allows</span></div>
<div style="position:absolute;left:5.00px;top:464.25px" class="cls_004"><span class="cls_004">only unique values to be added.</span></div>
<div style="position:absolute;left:5.00px;top:482.25px" class="cls_004"><span class="cls_004">Next, we iterate through our source collection, of type </span><span class="cls_007">User</span><span class="cls_004"> in this case, and attempt to add</span></div>
<div style="position:absolute;left:5.00px;top:500.25px" class="cls_004"><span class="cls_004">the relevant property value of each item in the collection into the </span><span class="cls_007">HashSet</span><span class="cls_004">. In our case, we're</span></div>
<div style="position:absolute;left:5.00px;top:518.25px" class="cls_004"><span class="cls_004">adding the names of the departments into this </span><span class="cls_007">HashSet</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:536.25px" class="cls_004"><span class="cls_004">If the department value is unique and the </span><span class="cls_007">HashSet<T>.Add</span><span class="cls_004"> method returns </span><span class="cls_007">true</span><span class="cls_004">, we yield, or</span></div>
<div style="position:absolute;left:5.00px;top:554.25px" class="cls_004"><span class="cls_004">return that item from our source collection. The second and each subsequent time that a</span></div>
<div style="position:absolute;left:5.00px;top:572.25px" class="cls_004"><span class="cls_004">used department value is read, it is rejected. This means that only the first items with</span></div>
<div style="position:absolute;left:5.00px;top:590.25px" class="cls_004"><span class="cls_004">unique department values are returned from this method.</span></div>
<div style="position:absolute;left:5.00px;top:608.25px" class="cls_004"><span class="cls_004">We've now managed to create our very own LINQ-style Extension method. However, not all</span></div>
<div style="position:absolute;left:5.00px;top:626.25px" class="cls_004"><span class="cls_004">of our Extension methods need to be so ground breaking. Often, they can be used to simply</span></div>
<div style="position:absolute;left:5.00px;top:644.25px" class="cls_004"><span class="cls_004">encapsulate some commonly used functionality. In a way, we can use them as simple</span></div>
<div style="position:absolute;left:5.00px;top:662.25px" class="cls_004"><span class="cls_004">convenience methods. Take a look at the following example that is used in the </span><span class="cls_006">With</span></div>
<div style="position:absolute;left:5.00px;top:681.00px" class="cls_006"><span class="cls_006">Converters</span><span class="cls_004"> section later in this chapter.</span></div>
<div style="position:absolute;left:52.98px;top:705.00px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.Extensions</span></div>
<div style="position:absolute;left:52.98px;top:718.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:732.00px" class="cls_007"><span class="cls_007">public static class EnumExtensions</span></div>
<div style="position:absolute;left:67.97px;top:745.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:759.00px" class="cls_007"><span class="cls_007">public static string GetDescription(this Enum value)</span></div>
<div style="position:absolute;left:82.97px;top:772.50px" class="cls_007"><span class="cls_007">{</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:58546px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background075.jpg" width=612 height=792></div>
<div style="position:absolute;left:97.96px;top:3.00px" class="cls_007"><span class="cls_007">FieldInfo fieldInfo =</span></div>
<div style="position:absolute;left:52.98px;top:16.50px" class="cls_007"><span class="cls_007">value.GetType().GetField(value.ToString());</span></div>
<div style="position:absolute;left:97.96px;top:30.00px" class="cls_007"><span class="cls_007">if (fieldInfo == null) Enum.GetName(value.GetType(), value);</span></div>
<div style="position:absolute;left:97.96px;top:43.50px" class="cls_007"><span class="cls_007">DescriptionAttribute[] attributes = (DescriptionAttribute[])</span></div>
<div style="position:absolute;left:112.96px;top:57.00px" class="cls_007"><span class="cls_007">fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute),</span></div>
<div style="position:absolute;left:52.98px;top:70.50px" class="cls_007"><span class="cls_007">false);</span></div>
<div style="position:absolute;left:97.96px;top:84.00px" class="cls_007"><span class="cls_007">if (attributes != null && attributes.Length > 0)</span></div>
<div style="position:absolute;left:112.96px;top:97.50px" class="cls_007"><span class="cls_007">return attributes[0].Description;</span></div>
<div style="position:absolute;left:97.96px;top:111.00px" class="cls_007"><span class="cls_007">return Enum.GetName(value.GetType(), value);</span></div>
<div style="position:absolute;left:82.97px;top:124.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:138.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:151.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:171.75px" class="cls_004"><span class="cls_004">In this method, we attempt to get the </span><span class="cls_007">FieldInfo</span><span class="cls_004"> object that relates to the instance of the</span></div>
<div style="position:absolute;left:5.00px;top:189.75px" class="cls_004"><span class="cls_004">relevant enumeration provided by the </span><span class="cls_007">value</span><span class="cls_004"> input parameter. If the attempt fails, we simply</span></div>
<div style="position:absolute;left:5.00px;top:207.75px" class="cls_004"><span class="cls_004">return the name of the particular instance. If we succeed however, we then use the</span></div>
<div style="position:absolute;left:5.00px;top:225.75px" class="cls_007"><span class="cls_007">GetCustomAttributes</span><span class="cls_004"> method of that object, passing the type of the </span><span class="cls_007">DescriptionAttribute</span></div>
<div style="position:absolute;left:5.00px;top:243.75px" class="cls_004"><span class="cls_004">class, to retrieve an array of attributes.</span></div>
<div style="position:absolute;left:5.00px;top:261.75px" class="cls_004"><span class="cls_004">If we have declared a value in the </span><span class="cls_007">DescriptionAttribute</span><span class="cls_004"> of this particular enumeration</span></div>
<div style="position:absolute;left:5.00px;top:279.75px" class="cls_004"><span class="cls_004">instance, then it will always be the first item in the attribute array. If we have not set a</span></div>
<div style="position:absolute;left:5.00px;top:297.75px" class="cls_004"><span class="cls_004">value, then the array will be empty and we return the name of the instance instead. Note</span></div>
<div style="position:absolute;left:5.00px;top:315.75px" class="cls_004"><span class="cls_004">that as we used the base </span><span class="cls_007">Enum</span><span class="cls_004"> class in this method, we are able to call this method on any</span></div>
<div style="position:absolute;left:5.00px;top:333.75px" class="cls_004"><span class="cls_004">enumeration type.</span></div>
<div style="position:absolute;left:5.00px;top:351.75px" class="cls_004"><span class="cls_004">When creating these methods, it should be noted that there is no requirement to put them</span></div>
<div style="position:absolute;left:5.00px;top:369.75px" class="cls_004"><span class="cls_004">into separate classes that are split by type, as we have done here. There are no specified</span></div>
<div style="position:absolute;left:5.00px;top:387.75px" class="cls_004"><span class="cls_004">naming conventions either and in fact, it is also totally viable to put all of your Extension</span></div>
<div style="position:absolute;left:5.00px;top:405.75px" class="cls_004"><span class="cls_004">methods into a single class. However, if we have a large number of Extension methods of a</span></div>
<div style="position:absolute;left:5.00px;top:423.75px" class="cls_004"><span class="cls_004">particular type, then it can help with maintenance to have this separation.</span></div>
<div style="position:absolute;left:5.00px;top:441.75px" class="cls_004"><span class="cls_004">Before moving on, let's take a look at one final example of these Extension methods. One</span></div>
<div style="position:absolute;left:5.00px;top:459.75px" class="cls_004"><span class="cls_004">of the most useful traits of an Extension method is the ability to add new or missing</span></div>
<div style="position:absolute;left:5.00px;top:477.75px" class="cls_004"><span class="cls_004">functionality to existing classes from the .NET Framework. For example, let's see how we</span></div>
<div style="position:absolute;left:5.00px;top:495.75px" class="cls_004"><span class="cls_004">can define a simple </span><span class="cls_007">Count</span><span class="cls_004"> method for the </span><span class="cls_007">IEnumerable</span><span class="cls_004"> class:</span></div>
<div style="position:absolute;left:52.98px;top:519.00px" class="cls_007"><span class="cls_007">public static int Count(this IEnumerable collection)</span></div>
<div style="position:absolute;left:52.98px;top:532.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:546.00px" class="cls_007"><span class="cls_007">int count = 0;</span></div>
<div style="position:absolute;left:67.97px;top:559.50px" class="cls_007"><span class="cls_007">foreach (object item in collection) count++;</span></div>
<div style="position:absolute;left:67.97px;top:573.00px" class="cls_007"><span class="cls_007">return count;</span></div>
<div style="position:absolute;left:52.98px;top:586.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:606.75px" class="cls_004"><span class="cls_004">As we can see, this method requires little explanation. It literally just counts the number of</span></div>
<div style="position:absolute;left:5.00px;top:624.75px" class="cls_004"><span class="cls_004">items in the </span><span class="cls_007">IEnumerable</span><span class="cls_004"> collection and returns that value. As simple as it is, it proves to be</span></div>
<div style="position:absolute;left:5.00px;top:642.75px" class="cls_004"><span class="cls_004">useful, as we'll see in a later example. Now that we have investigated Extension methods,</span></div>
<div style="position:absolute;left:5.00px;top:660.75px" class="cls_004"><span class="cls_004">let's turn our attention to another way of building further abilities into our framework, this</span></div>
<div style="position:absolute;left:5.00px;top:678.75px" class="cls_004"><span class="cls_004">time focusing on the Views component.</span></div>
<div style="position:absolute;left:5.00px;top:696.01px" class="cls_011"><span class="cls_011">In UI controls</span></div>
<div style="position:absolute;left:5.00px;top:726.00px" class="cls_004"><span class="cls_004">One other common way to include functionality in an application framework is to</span></div>
<div style="position:absolute;left:5.00px;top:744.00px" class="cls_004"><span class="cls_004">encapsulate it into custom controls. In doing so, we can expose the required functionality</span></div>
<div style="position:absolute;left:5.00px;top:762.00px" class="cls_004"><span class="cls_004">using Dependency Properties, while hiding the implementation details. This is also another</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:59348px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background076.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">great way to promote reusability and consistency throughout the application. Let's take a</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">look at a simple example of a </span><span class="cls_007">UserControl</span><span class="cls_004"> that wraps the functionality of the</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_007"><span class="cls_007">System.Windows.Forms.FolderBrowserDialog</span><span class="cls_004"> control:</span></div>
<div style="position:absolute;left:52.98px;top:63.00px" class="cls_007"><span class="cls_007"><UserControl</span></div>
<div style="position:absolute;left:52.98px;top:90.00px" class="cls_007"><span class="cls_007">x:Class="CompanyName.ApplicationName.Views.Controls.FolderPathEditF</span></div>
<div style="position:absolute;left:52.98px;top:103.50px" class="cls_007"><span class="cls_007">ield"</span></div>
<div style="position:absolute;left:67.97px;top:117.00px" class="cls_007"><span class="cls_007">xmlns="</span><A HREF="http://schemas.microsoft.com/winfx/2006/xaml/presentation"/">http://schemas.microsoft.com/winfx/2006/xaml/presentation"</A> </div>
<div style="position:absolute;left:67.97px;top:130.50px" class="cls_007"><span class="cls_007">xmlns:x="</span><A HREF="http://schemas.microsoft.com/winfx/2006/xaml"/">http://schemas.microsoft.com/winfx/2006/xaml"</A> </div>
<div style="position:absolute;left:67.97px;top:144.00px" class="cls_007"><span class="cls_007">xmlns:mc="</span><A HREF="http://schemas.openxmlformats.org/markup-/">http://schemas.openxmlformats.org/markup-</A> </div>
<div style="position:absolute;left:52.98px;top:157.50px" class="cls_007"><span class="cls_007">compatibility/2006"</span></div>
<div style="position:absolute;left:67.97px;top:171.00px" class="cls_007"><span class="cls_007">xmlns:d="</span><A HREF="http://schemas.microsoft.com/expression/blend/2008"/">http://schemas.microsoft.com/expression/blend/2008"</A> </div>
<div style="position:absolute;left:67.97px;top:184.50px" class="cls_007"><span class="cls_007">xmlns:Controls="clr-</span></div>
<div style="position:absolute;left:52.98px;top:198.00px" class="cls_007"><span class="cls_007">namespace:CompanyName.ApplicationName.Views.Controls"</span></div>
<div style="position:absolute;left:67.97px;top:211.50px" class="cls_007"><span class="cls_007">mc:Ignorable="d" d:DesignHeight="28" d:DesignWidth="300"></span></div>
<div style="position:absolute;left:67.97px;top:225.00px" class="cls_007"><span class="cls_007"><TextBox Name="FolderPathTextBox"</span></div>
<div style="position:absolute;left:82.97px;top:238.50px" class="cls_007"><span class="cls_007">Text="{Binding FolderPath, RelativeSource={RelativeSource</span></div>
<div style="position:absolute;left:82.97px;top:252.00px" class="cls_007"><span class="cls_007">AncestorType={x:Type Controls:FolderPathEditField}},</span></div>
<div style="position:absolute;left:52.98px;top:265.50px" class="cls_007"><span class="cls_007">FallbackValue='',</span></div>
<div style="position:absolute;left:82.97px;top:279.00px" class="cls_007"><span class="cls_007">UpdateSourceTrigger=PropertyChanged}" Cursor="Arrow"</span></div>
<div style="position:absolute;left:82.97px;top:292.50px" class="cls_007"><span class="cls_007">PreviewMouseLeftButtonUp="TextBox_PreviewMouseLeftButtonUp" /></span></div>
<div style="position:absolute;left:52.98px;top:306.00px" class="cls_007"><span class="cls_007"></UserControl></span></div>
<div style="position:absolute;left:5.00px;top:339.00px" class="cls_004"><span class="cls_004">This simple </span><span class="cls_007">UserControl</span><span class="cls_004"> just contains a textbox with its </span><span class="cls_007">Text</span><span class="cls_004"> property data bound to the</span></div>
<div style="position:absolute;left:5.00px;top:357.00px" class="cls_007"><span class="cls_007">FolderPath</span><span class="cls_004"> Dependency Property that is declared in our control's code behind. Remember</span></div>
<div style="position:absolute;left:5.00px;top:375.00px" class="cls_004"><span class="cls_004">that it is perfectly acceptable to use the code behind of a </span><span class="cls_007">UserControl</span><span class="cls_004"> for this purpose</span></div>
<div style="position:absolute;left:5.00px;top:393.00px" class="cls_004"><span class="cls_004">when using MVVM. Note that we have used a </span><span class="cls_007">RelativeSource</span><span class="cls_004"> binding here, because</span></div>
<div style="position:absolute;left:5.00px;top:411.00px" class="cls_004"><span class="cls_004">nothing has been set to this control's </span><span class="cls_007">DataContext</span><span class="cls_004"> property. We'll find out much more about</span></div>
<div style="position:absolute;left:5.00px;top:429.00px" class="cls_004"><span class="cls_004">data binding in the next chapter, but for now, let's continue.</span></div>
<div style="position:absolute;left:5.00px;top:447.00px" class="cls_004"><span class="cls_004">You may notice that we have attached a handler for the </span><span class="cls_007">PreviewMouseLeftButtonUp</span><span class="cls_004"> event in</span></div>
<div style="position:absolute;left:5.00px;top:465.00px" class="cls_004"><span class="cls_004">the code behind and as no business-related code is being used there, this is also perfectly</span></div>
<div style="position:absolute;left:5.00px;top:483.00px" class="cls_004"><span class="cls_004">acceptable when using MVVM. The only other notable code here is that we set the </span><span class="cls_007">Cursor</span></div>
<div style="position:absolute;left:5.00px;top:501.00px" class="cls_004"><span class="cls_004">property to show an arrow when users mouse over our control. Let's now take a look at the</span></div>
<div style="position:absolute;left:5.00px;top:519.00px" class="cls_004"><span class="cls_004">code behind of the </span><span class="cls_007">UserControl</span><span class="cls_004"> and see how the functionality is encapsulated:</span></div>
<div style="position:absolute;left:52.98px;top:542.25px" class="cls_007"><span class="cls_007">using System;</span></div>
<div style="position:absolute;left:52.98px;top:555.75px" class="cls_007"><span class="cls_007">using System.Windows;</span></div>
<div style="position:absolute;left:52.98px;top:569.25px" class="cls_007"><span class="cls_007">using System.Windows.Controls;</span></div>
<div style="position:absolute;left:52.98px;top:582.75px" class="cls_007"><span class="cls_007">using System.Windows.Input;</span></div>
<div style="position:absolute;left:52.98px;top:596.25px" class="cls_007"><span class="cls_007">using FolderBrowserDialog =</span></div>
<div style="position:absolute;left:52.98px;top:609.75px" class="cls_007"><span class="cls_007">System.Windows.Forms.FolderBrowserDialog;</span></div>
<div style="position:absolute;left:52.98px;top:636.75px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.Views.Controls</span></div>
<div style="position:absolute;left:52.98px;top:650.25px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:663.75px" class="cls_007"><span class="cls_007">public partial class FolderPathEditField : UserControl</span></div>
<div style="position:absolute;left:67.97px;top:677.25px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:690.75px" class="cls_007"><span class="cls_007">public FolderPathEditField()</span></div>
<div style="position:absolute;left:82.97px;top:704.25px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:717.75px" class="cls_007"><span class="cls_007">InitializeComponent();</span></div>
<div style="position:absolute;left:82.97px;top:731.25px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:758.25px" class="cls_007"><span class="cls_007">public static readonly DependencyProperty FolderPathProperty =</span></div>
<div style="position:absolute;left:97.96px;top:771.75px" class="cls_007"><span class="cls_007">DependencyProperty.Register(nameof(FolderPath),</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:60150px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background077.jpg" width=612 height=792></div>
<div style="position:absolute;left:97.96px;top:3.00px" class="cls_007"><span class="cls_007">typeof(string), typeof(FolderPathEditField),</span></div>
<div style="position:absolute;left:97.96px;top:16.50px" class="cls_007"><span class="cls_007">new FrameworkPropertyMetadata(string.Empty,</span></div>
<div style="position:absolute;left:97.96px;top:30.00px" class="cls_007"><span class="cls_007">FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));</span></div>
<div style="position:absolute;left:82.97px;top:57.00px" class="cls_007"><span class="cls_007">public string FolderPath</span></div>
<div style="position:absolute;left:82.97px;top:70.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:84.00px" class="cls_007"><span class="cls_007">get { return (string)GetValue(FolderPathProperty); }</span></div>
<div style="position:absolute;left:97.96px;top:97.50px" class="cls_007"><span class="cls_007">set { SetValue(FolderPathProperty, value); }</span></div>
<div style="position:absolute;left:82.97px;top:111.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:138.00px" class="cls_007"><span class="cls_007">public static readonly DependencyProperty</span></div>
<div style="position:absolute;left:52.98px;top:151.50px" class="cls_007"><span class="cls_007">OpenFolderTitleProperty =</span></div>
<div style="position:absolute;left:97.96px;top:165.00px" class="cls_007"><span class="cls_007">DependencyProperty.Register(nameof(OpenFolderTitle),</span></div>
<div style="position:absolute;left:97.96px;top:178.50px" class="cls_007"><span class="cls_007">typeof(string), typeof(FolderPathEditField),</span></div>
<div style="position:absolute;left:97.96px;top:192.00px" class="cls_007"><span class="cls_007">new FrameworkPropertyMetadata(string.Empty,</span></div>
<div style="position:absolute;left:97.96px;top:205.50px" class="cls_007"><span class="cls_007">FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));</span></div>
<div style="position:absolute;left:82.97px;top:232.50px" class="cls_007"><span class="cls_007">public string OpenFolderTitle</span></div>
<div style="position:absolute;left:82.97px;top:246.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:259.50px" class="cls_007"><span class="cls_007">get { return (string)GetValue(OpenFolderTitleProperty); }</span></div>
<div style="position:absolute;left:97.96px;top:273.00px" class="cls_007"><span class="cls_007">set { SetValue(OpenFolderTitleProperty, value); }</span></div>
<div style="position:absolute;left:82.97px;top:286.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:313.50px" class="cls_007"><span class="cls_007">private void TextBox_PreviewMouseLeftButtonUp(object sender,</span></div>
<div style="position:absolute;left:97.96px;top:327.00px" class="cls_007"><span class="cls_007">MouseButtonEventArgs e)</span></div>
<div style="position:absolute;left:82.97px;top:340.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:354.00px" class="cls_007"><span class="cls_007">if (((TextBox)sender).SelectedText.Length == 0 &&</span></div>
<div style="position:absolute;left:112.96px;top:367.50px" class="cls_007"><span class="cls_007">e.GetPosition(this).X <= ((TextBox)sender).ActualWidth -</span></div>
<div style="position:absolute;left:112.96px;top:381.00px" class="cls_007"><span class="cls_007">SystemParameters.VerticalScrollBarWidth)</span></div>
<div style="position:absolute;left:112.96px;top:394.50px" class="cls_007"><span class="cls_007">ShowFolderPathEditWindow();</span></div>
<div style="position:absolute;left:82.97px;top:408.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:435.00px" class="cls_007"><span class="cls_007">private void ShowFolderPathEditWindow()</span></div>
<div style="position:absolute;left:82.97px;top:448.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:462.00px" class="cls_007"><span class="cls_007">string defaultFolderPath = string.IsNullOrEmpty(FolderPath) ?</span></div>
<div style="position:absolute;left:52.98px;top:489.00px" class="cls_007"><span class="cls_007">Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)</span></div>
<div style="position:absolute;left:112.96px;top:502.50px" class="cls_007"><span class="cls_007">: FolderPath;</span></div>
<div style="position:absolute;left:97.96px;top:516.00px" class="cls_007"><span class="cls_007">string folderPath =</span></div>
<div style="position:absolute;left:52.98px;top:529.50px" class="cls_007"><span class="cls_007">ShowFolderBrowserDialog(defaultFolderPath);</span></div>
<div style="position:absolute;left:97.96px;top:543.00px" class="cls_007"><span class="cls_007">if (folderPath == string.Empty) return;</span></div>
<div style="position:absolute;left:97.96px;top:556.50px" class="cls_007"><span class="cls_007">FolderPath = folderPath;</span></div>
<div style="position:absolute;left:82.97px;top:570.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:597.00px" class="cls_007"><span class="cls_007">private string ShowFolderBrowserDialog(string</span></div>
<div style="position:absolute;left:52.98px;top:610.50px" class="cls_007"><span class="cls_007">defaultFolderPath)</span></div>
<div style="position:absolute;left:82.97px;top:624.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:637.50px" class="cls_007"><span class="cls_007">FolderBrowserDialog folderBrowserDialog = new</span></div>
<div style="position:absolute;left:52.98px;top:651.00px" class="cls_007"><span class="cls_007">FolderBrowserDialog();</span></div>
<div style="position:absolute;left:97.96px;top:664.50px" class="cls_007"><span class="cls_007">folderBrowserDialog.Description = OpenFolderTitle;</span></div>
<div style="position:absolute;left:97.96px;top:678.00px" class="cls_007"><span class="cls_007">folderBrowserDialog.ShowNewFolderButton = true;</span></div>
<div style="position:absolute;left:97.96px;top:691.50px" class="cls_007"><span class="cls_007">folderBrowserDialog.SelectedPath = defaultFolderPath;</span></div>
<div style="position:absolute;left:97.96px;top:705.00px" class="cls_007"><span class="cls_007">folderBrowserDialog.ShowDialog();</span></div>
<div style="position:absolute;left:97.96px;top:718.50px" class="cls_007"><span class="cls_007">return folderBrowserDialog.SelectedPath;</span></div>
<div style="position:absolute;left:82.97px;top:732.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:745.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:759.00px" class="cls_007"><span class="cls_007">}</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:60952px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background078.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:9.00px" class="cls_004"><span class="cls_004">We start with our </span><span class="cls_007">using</span><span class="cls_004"> directives and see an example of a using alias directive. In this</span></div>
<div style="position:absolute;left:5.00px;top:27.00px" class="cls_004"><span class="cls_004">case, we don't want to add a normal </span><span class="cls_007">using</span><span class="cls_004"> directive for the </span><span class="cls_007">System.Windows.Forms</span></div>
<div style="position:absolute;left:5.00px;top:45.00px" class="cls_004"><span class="cls_004">assembly because it contains many UI-related classes that have names that clash with</span></div>
<div style="position:absolute;left:5.00px;top:63.00px" class="cls_004"><span class="cls_004">those in the required </span><span class="cls_007">System.Windows</span><span class="cls_004"> assembly.</span></div>
<div style="position:absolute;left:5.00px;top:81.00px" class="cls_004"><span class="cls_004">To avoid these conflicts, we can create an alias for the single type that we are interested in</span></div>
<div style="position:absolute;left:5.00px;top:99.00px" class="cls_004"><span class="cls_004">using from that assembly. To clarify, Microsoft decided not to reinvent the wheel, or in this</span></div>
<div style="position:absolute;left:5.00px;top:117.00px" class="cls_004"><span class="cls_004">case, the </span><span class="cls_007">FolderBrowserDialog</span><span class="cls_004"> control, in the </span><span class="cls_007">System.Windows</span><span class="cls_004"> assembly and so we need</span></div>
<div style="position:absolute;left:5.00px;top:135.00px" class="cls_004"><span class="cls_004">to use the one from the </span><span class="cls_007">System.Windows.Forms</span><span class="cls_004"> assembly.</span></div>
<div style="position:absolute;left:5.00px;top:153.00px" class="cls_004"><span class="cls_004">Looking at this class, we see that much of this code is taken up with the declarations of the</span></div>
<div style="position:absolute;left:5.00px;top:171.00px" class="cls_004"><span class="cls_004">Dependency Properties of the control. We have the </span><span class="cls_007">FolderPath</span><span class="cls_004"> property that will hold the</span></div>
<div style="position:absolute;left:5.00px;top:189.00px" class="cls_004"><span class="cls_004">file path of the folder that is selected from the </span><span class="cls_007">Windows.Forms</span><span class="cls_004"> control and the</span></div>
<div style="position:absolute;left:5.00px;top:207.00px" class="cls_007"><span class="cls_007">OpenFolderTitle</span><span class="cls_004"> property that will populate the title bar of the </span><span class="cls_007">FolderBrowserDialog</span></div>
<div style="position:absolute;left:5.00px;top:225.00px" class="cls_004"><span class="cls_004">window when displayed.</span></div>
<div style="position:absolute;left:5.00px;top:243.00px" class="cls_004"><span class="cls_004">Next, we see the </span><span class="cls_007">TextBox_PreviewMouseLeftButtonUp</span><span class="cls_004"> event handler that handles the</span></div>
<div style="position:absolute;left:5.00px;top:261.00px" class="cls_007"><span class="cls_007">PreviewMouseLeftButtonUp</span><span class="cls_004"> event of the single textbox in our control. In this method, we</span></div>
<div style="position:absolute;left:5.00px;top:279.00px" class="cls_004"><span class="cls_004">first verify that the user is not selecting text from, or scrolling the textbox and then if true,</span></div>
<div style="position:absolute;left:5.00px;top:297.00px" class="cls_004"><span class="cls_004">we call the </span><span class="cls_007">ShowFolderPathEditWindow</span><span class="cls_004"> method.</span></div>
<div style="position:absolute;left:5.00px;top:315.00px" class="cls_004"><span class="cls_004">In order to verify that the user is not selecting text, we simply check the length of the</span></div>
<div style="position:absolute;left:5.00px;top:333.00px" class="cls_007"><span class="cls_007">SelectedText</span><span class="cls_004"> property of the </span><span class="cls_007">TextBox</span><span class="cls_004">. In order to confirm that the user is not scrolling the</span></div>
<div style="position:absolute;left:5.00px;top:351.00px" class="cls_004"><span class="cls_004">textbox, we compare the relative horizontal position of the user's click with the length of the</span></div>
<div style="position:absolute;left:5.00px;top:369.00px" class="cls_007"><span class="cls_007">TextBox</span><span class="cls_004"> minus the width of the vertical scroll bar to ensure that their mouse is not over the</span></div>
<div style="position:absolute;left:5.00px;top:387.00px" class="cls_004"><span class="cls_004">scroll bar.</span></div>
<div style="position:absolute;left:5.00px;top:405.00px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">ShowFolderPathEditWindow</span><span class="cls_004"> method first prepares to display the </span><span class="cls_007">Windows.Forms</span></div>
<div style="position:absolute;left:5.00px;top:423.00px" class="cls_004"><span class="cls_004">control. It sets the </span><span class="cls_007">defaultFolderPath</span><span class="cls_004"> variable to either the current value of the </span><span class="cls_007">FolderPath</span></div>
<div style="position:absolute;left:5.00px;top:441.00px" class="cls_004"><span class="cls_004">property, if one is set, or the current user's </span><span class="cls_007">Documents</span><span class="cls_004"> folder, using the</span></div>
<div style="position:absolute;left:5.00px;top:459.00px" class="cls_007"><span class="cls_007">Environment.GetFolderPath</span><span class="cls_004"> method and the </span><span class="cls_007">Environment.SpecialFolder.MyDocuments</span></div>
<div style="position:absolute;left:5.00px;top:477.00px" class="cls_004"><span class="cls_004">enumeration.</span></div>
<div style="position:absolute;left:5.00px;top:495.00px" class="cls_004"><span class="cls_004">It then calls the </span><span class="cls_007">ShowFolderBrowserDialog</span><span class="cls_004"> method to launch the actual</span></div>
<div style="position:absolute;left:5.00px;top:513.00px" class="cls_007"><span class="cls_007">FolderBrowserDialog</span><span class="cls_004"> control and retrieve the selected folder path. If a valid folder path is</span></div>
<div style="position:absolute;left:5.00px;top:531.00px" class="cls_004"><span class="cls_004">selected, we set its value to the data bound </span><span class="cls_007">FolderPath</span><span class="cls_004"> property directly, but note that we</span></div>
<div style="position:absolute;left:5.00px;top:549.00px" class="cls_004"><span class="cls_004">could have set it in other ways.</span></div>
<div style="position:absolute;left:5.00px;top:567.00px" class="cls_004"><span class="cls_004">It would be very easy to add an </span><span class="cls_007">ICommand</span><span class="cls_004"> property to our control in order to return the</span></div>
<div style="position:absolute;left:5.00px;top:585.00px" class="cls_004"><span class="cls_004">selected folder path instead of using this direct assignment. This could be useful in cases</span></div>
<div style="position:absolute;left:5.00px;top:603.00px" class="cls_004"><span class="cls_004">where we don't want the data bound value to be set instantly, for example, if the control</span></div>
<div style="position:absolute;left:5.00px;top:621.00px" class="cls_004"><span class="cls_004">was used in a child window that needed a confirmation button to be clicked before the data</span></div>
<div style="position:absolute;left:5.00px;top:639.00px" class="cls_004"><span class="cls_004">bound value could be updated.</span></div>
<div style="position:absolute;left:5.00px;top:657.00px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">ShowFolderBrowserDialog</span><span class="cls_004"> method utilizes the </span><span class="cls_007">defaultFolderPath</span><span class="cls_004"> variable and the</span></div>
<div style="position:absolute;left:5.00px;top:675.00px" class="cls_007"><span class="cls_007">OpenFolderTitle</span><span class="cls_004"> property when setting up the actual </span><span class="cls_007">FolderBrowserDialog</span><span class="cls_004"> control. Note</span></div>
<div style="position:absolute;left:5.00px;top:693.00px" class="cls_004"><span class="cls_004">that this </span><span class="cls_007">OpenFolderTitle</span><span class="cls_004"> property is simply here to demonstrate how we can expose the</span></div>
<div style="position:absolute;left:5.00px;top:711.00px" class="cls_004"><span class="cls_004">required properties from the </span><span class="cls_007">FolderBrowserDialog</span><span class="cls_004"> element in our control. In this way, we</span></div>
<div style="position:absolute;left:5.00px;top:729.00px" class="cls_004"><span class="cls_004">can encapsulate the use of the </span><span class="cls_007">Windows.Forms</span><span class="cls_004"> control and assembly within our control.</span></div>
<div style="position:absolute;left:5.00px;top:747.00px" class="cls_004"><span class="cls_004">Note that we could have added extra Dependency Properties to enable the users of our</span></div>
<div style="position:absolute;left:5.00px;top:765.00px" class="cls_004"><span class="cls_004">framework to have further control over the settings in the </span><span class="cls_007">FolderBrowserDialog</span><span class="cls_004"> control. In</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:61754px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background079.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">this basic example, we simply hardcoded a positive value for the</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_007"><span class="cls_007">FolderBrowserDialog.ShowNewFolderButton</span><span class="cls_004"> property, but we could have exposed that as</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">another property.</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">We could have also added a browse button and maybe even a clear button to clear the</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">selected folder value. We could have then added additional </span><span class="cls_007">bool</span><span class="cls_004"> Dependency Properties to</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">control whether those buttons should be displayed or not. There are many other ways that</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">we could improve this control, but it still demonstrates how we can encapsulate functionality</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">into our Views components. We'll see another View-related way to capture little snippets of</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">functionality in the following section.</span></div>
<div style="position:absolute;left:5.00px;top:165.01px" class="cls_011"><span class="cls_011">With converters</span></div>
<div style="position:absolute;left:5.00px;top:195.00px" class="cls_004"><span class="cls_004">Converters are yet another way that we can package up useful functionality in our</span></div>
<div style="position:absolute;left:5.00px;top:213.00px" class="cls_004"><span class="cls_004">framework. We've already seen a useful example of the </span><span class="cls_007">IValueConverter</span><span class="cls_004"> interface in</span></div>
<div style="position:absolute;left:5.00px;top:231.00px" class="cls_015"><span class="cls_015">Chapter 2</span><span class="cls_004">, </span><span class="cls_006">Debugging WPF Applications</span><span class="cls_004">, but while that was a very simple example,</span></div>
<div style="position:absolute;left:5.00px;top:249.75px" class="cls_004"><span class="cls_004">converters can actually be very versatile.</span></div>
<div style="position:absolute;left:5.00px;top:267.75px" class="cls_004"><span class="cls_004">Long before Microsoft introduced their </span><span class="cls_007">BooleanToVisibilityConverter</span><span class="cls_004"> class, developers</span></div>
<div style="position:absolute;left:5.00px;top:285.75px" class="cls_004"><span class="cls_004">had to create their own versions. We often need to convert the </span><span class="cls_007">UIElement.Visibility</span></div>
<div style="position:absolute;left:5.00px;top:303.75px" class="cls_004"><span class="cls_004">enumeration to or from a variety of different types and so it is a good idea to start with a</span></div>
<div style="position:absolute;left:5.00px;top:321.75px" class="cls_007"><span class="cls_007">BaseVisibilityConverter</span><span class="cls_004"> class that can serve multiple converter classes. Let's see what</span></div>
<div style="position:absolute;left:5.00px;top:339.75px" class="cls_004"><span class="cls_004">that entails.</span></div>
<div style="position:absolute;left:52.98px;top:363.00px" class="cls_007"><span class="cls_007">using System.Windows;</span></div>
<div style="position:absolute;left:52.98px;top:376.50px" class="cls_007"><span class="cls_007">using System.Windows.Data;</span></div>
<div style="position:absolute;left:52.98px;top:403.50px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.Converters</span></div>
<div style="position:absolute;left:52.98px;top:417.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:430.50px" class="cls_007"><span class="cls_007">public abstract class BaseVisibilityConverter</span></div>
<div style="position:absolute;left:67.97px;top:444.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:457.50px" class="cls_007"><span class="cls_007">public enum FalseVisibility { Hidden, Collapsed }</span></div>
<div style="position:absolute;left:82.97px;top:484.50px" class="cls_007"><span class="cls_007">protected Visibility FalseVisibilityValue { get; set; } =</span></div>
<div style="position:absolute;left:97.96px;top:498.00px" class="cls_007"><span class="cls_007">Visibility.Collapsed;</span></div>
<div style="position:absolute;left:82.97px;top:525.00px" class="cls_007"><span class="cls_007">public FalseVisibility FalseVisibilityState</span></div>
<div style="position:absolute;left:82.97px;top:538.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:552.00px" class="cls_007"><span class="cls_007">get { return falseVisibilityState == Visibility.Collapsed ?</span></div>
<div style="position:absolute;left:112.96px;top:565.50px" class="cls_007"><span class="cls_007">FalseVisibility.Collapsed : FalseVisibility.Hidden; }</span></div>
<div style="position:absolute;left:97.96px;top:579.00px" class="cls_007"><span class="cls_007">set { falseVisibilityState = value ==</span></div>
<div style="position:absolute;left:52.98px;top:592.50px" class="cls_007"><span class="cls_007">FalseVisibility.Collapsed ?</span></div>
<div style="position:absolute;left:112.96px;top:606.00px" class="cls_007"><span class="cls_007">Visibility.Collapsed : Visibility.Hidden; }</span></div>
<div style="position:absolute;left:82.97px;top:619.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:646.50px" class="cls_007"><span class="cls_007">public bool IsInverted { get; set; }</span></div>
<div style="position:absolute;left:67.97px;top:660.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:673.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:706.50px" class="cls_004"><span class="cls_004">This converter requires one value to represent the visible value and as there is only one</span></div>
<div style="position:absolute;left:5.00px;top:724.50px" class="cls_004"><span class="cls_004">corresponding value in the </span><span class="cls_007">UIElement.Visibility</span><span class="cls_004"> enumeration, that will clearly be the</span></div>
<div style="position:absolute;left:5.00px;top:742.50px" class="cls_007"><span class="cls_007">Visibility.Visible</span><span class="cls_004"> instance. It also requires a single value to represent the invisible value.</span></div>
<div style="position:absolute;left:5.00px;top:760.50px" class="cls_004"><span class="cls_004">As such, we declare the </span><span class="cls_007">FalseVisibility</span><span class="cls_004"> enumeration with the two corresponding values</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:62556px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background080.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">from the </span><span class="cls_007">UIElement.Visibility</span><span class="cls_004"> enumeration and the </span><span class="cls_007">FalseVisibilityValue</span><span class="cls_004"> property to</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">enable users to specify which value should represent the false state. Note that the most</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">commonly used </span><span class="cls_007">Visibility.Collapsed</span><span class="cls_004"> value is set as the default value.</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">The users can set the </span><span class="cls_007">FalseVisibilityState</span><span class="cls_004"> property when using the control and this sets</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">the protected </span><span class="cls_007">FalseVisibilityValue</span><span class="cls_004"> property internally. Finally, we see the indispensable</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_007"><span class="cls_007">IsInverted</span><span class="cls_004"> property that is optionally used to invert the result. Let's see what our</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_007"><span class="cls_007">BoolToVisibilityConverter</span><span class="cls_004"> class looks like now:</span></div>
<div style="position:absolute;left:52.98px;top:135.00px" class="cls_007"><span class="cls_007">using System;</span></div>
<div style="position:absolute;left:52.98px;top:148.50px" class="cls_007"><span class="cls_007">using System.Globalization;</span></div>
<div style="position:absolute;left:52.98px;top:162.00px" class="cls_007"><span class="cls_007">using System.Windows;</span></div>
<div style="position:absolute;left:52.98px;top:175.50px" class="cls_007"><span class="cls_007">using System.Windows.Data;</span></div>
<div style="position:absolute;left:52.98px;top:202.50px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.Converters</span></div>
<div style="position:absolute;left:52.98px;top:216.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:229.50px" class="cls_007"><span class="cls_007">[ValueConversion(typeof(bool), typeof(Visibility))]</span></div>
<div style="position:absolute;left:67.97px;top:243.00px" class="cls_007"><span class="cls_007">public class BoolToVisibilityConverter : BaseVisibilityConverter,</span></div>
<div style="position:absolute;left:82.97px;top:256.50px" class="cls_007"><span class="cls_007">IValueConverter</span></div>
<div style="position:absolute;left:67.97px;top:270.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:283.50px" class="cls_007"><span class="cls_007">public object Convert(object value, Type targetType,</span></div>
<div style="position:absolute;left:97.96px;top:297.00px" class="cls_007"><span class="cls_007">object parameter, CultureInfo culture)</span></div>
<div style="position:absolute;left:82.97px;top:310.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:324.00px" class="cls_007"><span class="cls_007">if (value == null || value.GetType() != typeof(bool))</span></div>
<div style="position:absolute;left:112.96px;top:337.50px" class="cls_007"><span class="cls_007">return DependencyProperty.UnsetValue;</span></div>
<div style="position:absolute;left:97.96px;top:351.00px" class="cls_007"><span class="cls_007">bool boolValue = IsInverted ? !(bool)value :(bool)value;</span></div>
<div style="position:absolute;left:97.96px;top:364.50px" class="cls_007"><span class="cls_007">return boolValue ? Visibility.Visible : FalseVisibilityValue;</span></div>
<div style="position:absolute;left:82.97px;top:378.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:405.00px" class="cls_007"><span class="cls_007">public object ConvertBack(object value, Type targetType,</span></div>
<div style="position:absolute;left:97.96px;top:418.50px" class="cls_007"><span class="cls_007">object parameter, CultureInfo culture)</span></div>
<div style="position:absolute;left:82.97px;top:432.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:445.50px" class="cls_007"><span class="cls_007">if (value == null || value.GetType() != typeof(Visibility))</span></div>
<div style="position:absolute;left:112.96px;top:459.00px" class="cls_007"><span class="cls_007">return DependencyProperty.UnsetValue;</span></div>
<div style="position:absolute;left:97.96px;top:472.50px" class="cls_007"><span class="cls_007">if (IsInverted) return (Visibility)value !=</span></div>
<div style="position:absolute;left:52.98px;top:486.00px" class="cls_007"><span class="cls_007">Visibility.Visible;</span></div>
<div style="position:absolute;left:97.96px;top:499.50px" class="cls_007"><span class="cls_007">return (Visibility)value == Visibility.Visible;</span></div>
<div style="position:absolute;left:82.97px;top:513.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:526.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:540.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:573.00px" class="cls_004"><span class="cls_004">We start by specifying the data types involved in the implementation of the converter in the</span></div>
<div style="position:absolute;left:5.00px;top:591.00px" class="cls_007"><span class="cls_007">ValueConversion</span><span class="cls_004"> attribute. This helps tools to know what types are being used in the</span></div>
<div style="position:absolute;left:5.00px;top:609.00px" class="cls_004"><span class="cls_004">converter, but also makes it clear to the users of our framework. Next, we extend our</span></div>
<div style="position:absolute;left:5.00px;top:627.00px" class="cls_007"><span class="cls_007">BaseVisibilityConverter</span><span class="cls_004"> base class and extend the required </span><span class="cls_007">IValueConverter</span><span class="cls_004"> interface.</span></div>
<div style="position:absolute;left:5.00px;top:645.00px" class="cls_004"><span class="cls_004">In the </span><span class="cls_007">Convert</span><span class="cls_004"> method, we first check the validity of our </span><span class="cls_007">value</span><span class="cls_004"> input parameter, then if valid,</span></div>
<div style="position:absolute;left:5.00px;top:663.00px" class="cls_004"><span class="cls_004">we convert it to a </span><span class="cls_007">bool</span><span class="cls_004"> variable, taking the </span><span class="cls_007">IsInverted</span><span class="cls_004"> property setting into consideration.</span></div>
<div style="position:absolute;left:5.00px;top:681.00px" class="cls_004"><span class="cls_004">We return the </span><span class="cls_007">DependencyProperty.UnsetValue</span><span class="cls_004"> value for invalid input values. Finally, we</span></div>
<div style="position:absolute;left:5.00px;top:699.00px" class="cls_004"><span class="cls_004">resolve the output value from this </span><span class="cls_007">bool</span><span class="cls_004"> variable to either the </span><span class="cls_007">Visibility.Visible</span><span class="cls_004"> instance,</span></div>
<div style="position:absolute;left:5.00px;top:717.00px" class="cls_004"><span class="cls_004">or the value of the </span><span class="cls_007">FalseVisibilityValue</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:5.00px;top:735.00px" class="cls_004"><span class="cls_004">In the </span><span class="cls_007">ConvertBack</span><span class="cls_004"> method, we also check the validity of our </span><span class="cls_007">value</span><span class="cls_004"> input parameter first.</span></div>
<div style="position:absolute;left:5.00px;top:753.00px" class="cls_004"><span class="cls_004">We return the </span><span class="cls_007">DependencyProperty.UnsetValue</span><span class="cls_004"> value for invalid input values again,</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:63358px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background081.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">otherwise we output a </span><span class="cls_007">bool</span><span class="cls_004"> value that specifies whether the input parameter of type</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_007"><span class="cls_007">Visibility</span><span class="cls_004"> is equal to the </span><span class="cls_007">Visibility.Visible</span><span class="cls_004"> instance, while again taking the value of the</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_007"><span class="cls_007">IsInverted</span><span class="cls_004"> property into consideration.</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">Note that use of the </span><span class="cls_007">IsInverted</span><span class="cls_004"> property enables users to specify that elements should</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">become visible when the data bound </span><span class="cls_007">bool</span><span class="cls_004"> value is </span><span class="cls_007">false</span><span class="cls_004">. This can be incredibly useful when</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">we want to have one object visible upon a certain condition and another object hidden</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">dependent upon the same condition. We can declare two converters from this class like</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">this:</span></div>
<div style="position:absolute;left:52.98px;top:153.00px" class="cls_007"><span class="cls_007">xmlns:Converters="clr-</span></div>
<div style="position:absolute;left:52.98px;top:166.50px" class="cls_007"><span class="cls_007">namespace:CompanyName.ApplicationName.Converters;</span></div>
<div style="position:absolute;left:67.97px;top:180.00px" class="cls_007"><span class="cls_007">assembly=CompanyName.ApplicationName.Converters"</span></div>
<div style="position:absolute;left:52.98px;top:207.00px" class="cls_007"><span class="cls_007"><Converters:BoolToVisibilityConverter</span></div>
<div style="position:absolute;left:52.98px;top:220.50px" class="cls_007"><span class="cls_007">x:Key="BoolToVisibilityConverter" /></span></div>
<div style="position:absolute;left:52.98px;top:234.00px" class="cls_007"><span class="cls_007"><Converters:BoolToVisibilityConverter</span></div>
<div style="position:absolute;left:67.97px;top:247.50px" class="cls_007"><span class="cls_007">x:Key="InvertedBoolToVisibilityConverter" IsInverted="True" /></span></div>
<div style="position:absolute;left:5.00px;top:267.75px" class="cls_004"><span class="cls_004">As stated, we often need to convert to and from the </span><span class="cls_007">UIElement.Visibility</span><span class="cls_004"> enumeration</span></div>
<div style="position:absolute;left:5.00px;top:285.75px" class="cls_004"><span class="cls_004">from a variety of different types. Let's see an example of a conversion to and from the </span><span class="cls_007">Enum</span></div>
<div style="position:absolute;left:5.00px;top:303.75px" class="cls_004"><span class="cls_004">type now. The principle is the same as the last example, where a single data bound value</span></div>
<div style="position:absolute;left:5.00px;top:321.75px" class="cls_004"><span class="cls_004">represents the </span><span class="cls_007">Visibility.Visible</span><span class="cls_004"> instance and all other values represent the hidden or</span></div>
<div style="position:absolute;left:5.00px;top:339.75px" class="cls_004"><span class="cls_004">collapsed state:</span></div>
<div style="position:absolute;left:52.98px;top:363.00px" class="cls_007"><span class="cls_007">using System;</span></div>
<div style="position:absolute;left:52.98px;top:376.50px" class="cls_007"><span class="cls_007">using System.Globalization;</span></div>
<div style="position:absolute;left:52.98px;top:390.00px" class="cls_007"><span class="cls_007">using System.Windows;</span></div>
<div style="position:absolute;left:52.98px;top:403.50px" class="cls_007"><span class="cls_007">using System.Windows.Data;</span></div>
<div style="position:absolute;left:52.98px;top:430.50px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.Converters</span></div>
<div style="position:absolute;left:52.98px;top:444.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:457.50px" class="cls_007"><span class="cls_007">[ValueConversion(typeof(Enum), typeof(Visibility))]</span></div>
<div style="position:absolute;left:67.97px;top:471.00px" class="cls_007"><span class="cls_007">public class EnumToVisibilityConverter : BaseVisibilityConverter,</span></div>
<div style="position:absolute;left:82.97px;top:484.50px" class="cls_007"><span class="cls_007">IValueConverter</span></div>
<div style="position:absolute;left:67.97px;top:498.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:511.50px" class="cls_007"><span class="cls_007">public object Convert(object value, Type targetType,</span></div>
<div style="position:absolute;left:97.96px;top:525.00px" class="cls_007"><span class="cls_007">object parameter, CultureInfo culture)</span></div>
<div style="position:absolute;left:82.97px;top:538.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:552.00px" class="cls_007"><span class="cls_007">if (value == null || (value.GetType() != typeof(Enum) &&</span></div>
<div style="position:absolute;left:112.96px;top:565.50px" class="cls_007"><span class="cls_007">value.GetType().BaseType != typeof(Enum)) ||</span></div>
<div style="position:absolute;left:112.96px;top:579.00px" class="cls_007"><span class="cls_007">parameter == null) return DependencyProperty.UnsetValue;</span></div>
<div style="position:absolute;left:97.96px;top:592.50px" class="cls_007"><span class="cls_007">string enumValue = value.ToString();</span></div>
<div style="position:absolute;left:97.96px;top:606.00px" class="cls_007"><span class="cls_007">string targetValue = parameter.ToString();</span></div>
<div style="position:absolute;left:97.96px;top:619.50px" class="cls_007"><span class="cls_007">bool boolValue = enumValue.Equals(targetValue,</span></div>
<div style="position:absolute;left:112.96px;top:633.00px" class="cls_007"><span class="cls_007">StringComparison.InvariantCultureIgnoreCase);</span></div>
<div style="position:absolute;left:97.96px;top:646.50px" class="cls_007"><span class="cls_007">boolValue = IsInverted ? !boolValue : boolValue;</span></div>
<div style="position:absolute;left:97.96px;top:660.00px" class="cls_007"><span class="cls_007">return boolValue ? Visibility.Visible : FalseVisibilityValue;</span></div>
<div style="position:absolute;left:82.97px;top:673.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:700.50px" class="cls_007"><span class="cls_007">public object ConvertBack(object value, Type targetType,</span></div>
<div style="position:absolute;left:97.96px;top:714.00px" class="cls_007"><span class="cls_007">object parameter, CultureInfo culture)</span></div>
<div style="position:absolute;left:82.97px;top:727.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:741.00px" class="cls_007"><span class="cls_007">if (value == null || value.GetType() != typeof(Visibility) ||</span></div>
<div style="position:absolute;left:112.96px;top:754.50px" class="cls_007"><span class="cls_007">parameter == null) return DependencyProperty.UnsetValue;</span></div>
<div style="position:absolute;left:97.96px;top:768.00px" class="cls_007"><span class="cls_007">Visibility usedValue = (Visibility)value;</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:64160px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background082.jpg" width=612 height=792></div>
<div style="position:absolute;left:97.96px;top:3.00px" class="cls_007"><span class="cls_007">string targetValue = parameter.ToString();</span></div>
<div style="position:absolute;left:97.96px;top:16.50px" class="cls_007"><span class="cls_007">if (IsInverted && usedValue != Visibility.Visible)</span></div>
<div style="position:absolute;left:112.96px;top:30.00px" class="cls_007"><span class="cls_007">return Enum.Parse(targetType, targetValue);</span></div>
<div style="position:absolute;left:97.96px;top:43.50px" class="cls_007"><span class="cls_007">else if (!IsInverted && usedValue == Visibility.Visible)</span></div>
<div style="position:absolute;left:112.96px;top:57.00px" class="cls_007"><span class="cls_007">return Enum.Parse(targetType, targetValue);</span></div>
<div style="position:absolute;left:97.96px;top:70.50px" class="cls_007"><span class="cls_007">return DependencyProperty.UnsetValue;</span></div>
<div style="position:absolute;left:82.97px;top:84.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:97.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:111.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:144.00px" class="cls_004"><span class="cls_004">Again, we start by specifying the data types involved in the implementation of the converter</span></div>
<div style="position:absolute;left:5.00px;top:162.00px" class="cls_004"><span class="cls_004">in the </span><span class="cls_007">ValueConversion</span><span class="cls_004"> attribute. In the </span><span class="cls_007">Convert</span><span class="cls_004"> method, we first check the validity of our</span></div>
<div style="position:absolute;left:5.00px;top:180.00px" class="cls_007"><span class="cls_007">value</span><span class="cls_004"> input parameter, then if valid, we convert it to the string representation of the value.</span></div>
<div style="position:absolute;left:5.00px;top:198.00px" class="cls_004"><span class="cls_004">This particular class uses the </span><span class="cls_007">parameter</span><span class="cls_004"> input parameter to pass the specified enumeration</span></div>
<div style="position:absolute;left:5.00px;top:216.00px" class="cls_004"><span class="cls_004">instance that will represent the visible value and so it is set to the </span><span class="cls_007">targetValue</span><span class="cls_004"> variable as a</span></div>
<div style="position:absolute;left:5.00px;top:234.00px" class="cls_004"><span class="cls_004">string.</span></div>
<div style="position:absolute;left:5.00px;top:252.00px" class="cls_004"><span class="cls_004">We then create a </span><span class="cls_007">bool</span><span class="cls_004"> value by comparing the current enumeration instance with the target</span></div>
<div style="position:absolute;left:5.00px;top:270.00px" class="cls_004"><span class="cls_004">instance. Once we have our </span><span class="cls_007">bool</span><span class="cls_004"> value, the last two lines replicate those in the</span></div>
<div style="position:absolute;left:5.00px;top:288.00px" class="cls_007"><span class="cls_007">BoolToVisibilityConverter</span><span class="cls_004"> class.</span></div>
<div style="position:absolute;left:5.00px;top:306.00px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">ConvertBack</span><span class="cls_004"> method implementation is somewhat different. Logically speaking, we are</span></div>
<div style="position:absolute;left:5.00px;top:324.00px" class="cls_004"><span class="cls_004">unable to return the correct enumeration instance for a hidden visibility, as it could be any</span></div>
<div style="position:absolute;left:5.00px;top:342.00px" class="cls_004"><span class="cls_004">value except the visible value passed through the </span><span class="cls_007">parameter</span><span class="cls_004"> input parameter.</span></div>
<div style="position:absolute;left:5.00px;top:360.00px" class="cls_004"><span class="cls_004">As such, we are only able to return that specified value if the element is visible and the</span></div>
<div style="position:absolute;left:5.00px;top:378.00px" class="cls_007"><span class="cls_007">IsInverted</span><span class="cls_004"> property is </span><span class="cls_007">false</span><span class="cls_004">, or if it is not visible and the </span><span class="cls_007">IsInverted</span><span class="cls_004"> property is </span><span class="cls_007">true</span><span class="cls_004">. For</span></div>
<div style="position:absolute;left:5.00px;top:396.00px" class="cls_004"><span class="cls_004">all other input values, we simply return the </span><span class="cls_007">DependencyProperty.UnsetValue</span><span class="cls_004"> property to</span></div>
<div style="position:absolute;left:5.00px;top:414.00px" class="cls_004"><span class="cls_004">state that there is no value.</span></div>
<div style="position:absolute;left:5.00px;top:432.00px" class="cls_004"><span class="cls_004">Another incredibly useful thing that converters can do is to convert individual enumeration</span></div>
<div style="position:absolute;left:5.00px;top:450.00px" class="cls_004"><span class="cls_004">instances to particular images. Let's look at an example that relates to our</span></div>
<div style="position:absolute;left:5.00px;top:468.00px" class="cls_007"><span class="cls_007">FeedbackManager</span><span class="cls_004">, or more accurately, the </span><span class="cls_007">Feedback</span><span class="cls_004"> objects that get displayed. Each</span></div>
<div style="position:absolute;left:5.00px;top:486.00px" class="cls_007"><span class="cls_007">Feedback</span><span class="cls_004"> object can have a particular type that is specified by the </span><span class="cls_007">FeedbackType</span></div>
<div style="position:absolute;left:5.00px;top:504.00px" class="cls_004"><span class="cls_004">enumeration, so let's first see that.</span></div>
<div style="position:absolute;left:52.98px;top:527.25px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.DataModels.Enums</span></div>
<div style="position:absolute;left:52.98px;top:540.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:554.25px" class="cls_007"><span class="cls_007">public enum FeedbackType</span></div>
<div style="position:absolute;left:67.97px;top:567.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:581.25px" class="cls_007"><span class="cls_007">None = -1,</span></div>
<div style="position:absolute;left:82.97px;top:594.75px" class="cls_007"><span class="cls_007">Error,</span></div>
<div style="position:absolute;left:82.97px;top:608.25px" class="cls_007"><span class="cls_007">Information,</span></div>
<div style="position:absolute;left:82.97px;top:621.75px" class="cls_007"><span class="cls_007">Question,</span></div>
<div style="position:absolute;left:82.97px;top:635.25px" class="cls_007"><span class="cls_007">Success,</span></div>
<div style="position:absolute;left:82.97px;top:648.75px" class="cls_007"><span class="cls_007">Validation,</span></div>
<div style="position:absolute;left:82.97px;top:662.25px" class="cls_007"><span class="cls_007">Warning</span></div>
<div style="position:absolute;left:67.97px;top:675.75px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:689.25px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:709.50px" class="cls_004"><span class="cls_004">To make this work, we obviously need a suitable image for each enumeration instance,</span></div>
<div style="position:absolute;left:5.00px;top:727.50px" class="cls_004"><span class="cls_004">except for the </span><span class="cls_007">None</span><span class="cls_004"> instance. Our images will reside in the root folder of the startup project.</span></div>
<div style="position:absolute;left:52.98px;top:750.75px" class="cls_007"><span class="cls_007">using System;</span></div>
<div style="position:absolute;left:52.98px;top:764.25px" class="cls_007"><span class="cls_007">using System.Globalization;</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:64962px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background083.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:3.00px" class="cls_007"><span class="cls_007">using System.Windows;</span></div>
<div style="position:absolute;left:52.98px;top:16.50px" class="cls_007"><span class="cls_007">using System.Windows.Data;</span></div>
<div style="position:absolute;left:52.98px;top:30.00px" class="cls_007"><span class="cls_007">using System.Windows.Media;</span></div>
<div style="position:absolute;left:52.98px;top:43.50px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.DataModels.Enums;</span></div>
<div style="position:absolute;left:52.98px;top:70.50px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.Converters</span></div>
<div style="position:absolute;left:52.98px;top:84.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:97.50px" class="cls_007"><span class="cls_007">[ValueConversion(typeof(Enum), typeof(ImageSource))]</span></div>
<div style="position:absolute;left:67.97px;top:111.00px" class="cls_007"><span class="cls_007">public class FeedbackTypeToImageSourceConverter : IValueConverter</span></div>
<div style="position:absolute;left:67.97px;top:124.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:138.00px" class="cls_007"><span class="cls_007">public object Convert(object value, Type targetType,</span></div>
<div style="position:absolute;left:97.96px;top:151.50px" class="cls_007"><span class="cls_007">object parameter, CultureInfo culture)</span></div>
<div style="position:absolute;left:82.97px;top:165.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:178.50px" class="cls_007"><span class="cls_007">if (value == null || value.GetType() != typeof(FeedbackType)</span></div>
<div style="position:absolute;left:52.98px;top:192.00px" class="cls_007"><span class="cls_007">||</span></div>
<div style="position:absolute;left:112.96px;top:205.50px" class="cls_007"><span class="cls_007">targetType != typeof(ImageSource))</span></div>
<div style="position:absolute;left:112.96px;top:219.00px" class="cls_007"><span class="cls_007">return DependencyProperty.UnsetValue;</span></div>
<div style="position:absolute;left:97.96px;top:232.50px" class="cls_007"><span class="cls_007">string imageName = string.Empty;</span></div>
<div style="position:absolute;left:97.96px;top:246.00px" class="cls_007"><span class="cls_007">switch ((FeedbackType)value)</span></div>
<div style="position:absolute;left:97.96px;top:259.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:112.96px;top:273.00px" class="cls_007"><span class="cls_007">case FeedbackType.None: return null;</span></div>
<div style="position:absolute;left:112.96px;top:286.50px" class="cls_007"><span class="cls_007">case FeedbackType.Error: imageName = "Error_16"; break;</span></div>
<div style="position:absolute;left:112.96px;top:300.00px" class="cls_007"><span class="cls_007">case FeedbackType.Success: imageName = "Success_16"; break;</span></div>
<div style="position:absolute;left:112.96px;top:313.50px" class="cls_007"><span class="cls_007">case FeedbackType.Validation:</span></div>
<div style="position:absolute;left:112.96px;top:327.00px" class="cls_007"><span class="cls_007">case FeedbackType.Warning: imageName = "Warning_16"; break;</span></div>
<div style="position:absolute;left:112.96px;top:340.50px" class="cls_007"><span class="cls_007">case FeedbackType.Information: imageName =</span></div>
<div style="position:absolute;left:52.98px;top:354.00px" class="cls_007"><span class="cls_007">"Information_16"; break;</span></div>
<div style="position:absolute;left:112.96px;top:367.50px" class="cls_007"><span class="cls_007">case FeedbackType.Question: imageName = "Question_16";</span></div>
<div style="position:absolute;left:52.98px;top:381.00px" class="cls_007"><span class="cls_007">break;</span></div>
<div style="position:absolute;left:112.96px;top:394.50px" class="cls_007"><span class="cls_007">default: return DependencyProperty.UnsetValue;</span></div>
<div style="position:absolute;left:97.96px;top:408.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:97.96px;top:421.50px" class="cls_007"><span class="cls_007">return $"pack://application:,,,/CompanyName.ApplicationName;</span></div>
<div style="position:absolute;left:112.96px;top:435.00px" class="cls_007"><span class="cls_007">component/Images/{imageName}.png";</span></div>
<div style="position:absolute;left:82.97px;top:448.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:475.50px" class="cls_007"><span class="cls_007">public object ConvertBack(object value, Type targetType,</span></div>
<div style="position:absolute;left:97.96px;top:489.00px" class="cls_007"><span class="cls_007">object parameter, CultureInfo culture)</span></div>
<div style="position:absolute;left:82.97px;top:502.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:516.00px" class="cls_007"><span class="cls_007">return DependencyProperty.UnsetValue;</span></div>
<div style="position:absolute;left:82.97px;top:529.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:543.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:556.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:589.50px" class="cls_004"><span class="cls_004">Once again, we start by specifying the data types involved in the converter in the</span></div>
<div style="position:absolute;left:5.00px;top:607.50px" class="cls_007"><span class="cls_007">ValueConversion</span><span class="cls_004"> attribute. In the </span><span class="cls_007">Convert</span><span class="cls_004"> method, we check the validity of our </span><span class="cls_007">value</span><span class="cls_004"> input</span></div>
<div style="position:absolute;left:5.00px;top:625.50px" class="cls_004"><span class="cls_004">parameter before casting it to a </span><span class="cls_007">FeedbackType</span><span class="cls_004"> instance if valid. We then use a </span><span class="cls_007">switch</span></div>
<div style="position:absolute;left:5.00px;top:643.50px" class="cls_004"><span class="cls_004">statement to generate the relevant image name for each enumeration instance.</span></div>
<div style="position:absolute;left:5.00px;top:661.50px" class="cls_004"><span class="cls_004">If an unknown instance is used, we return the </span><span class="cls_007">DependencyProperty.UnsetValue</span><span class="cls_004"> value. In all</span></div>
<div style="position:absolute;left:5.00px;top:679.50px" class="cls_004"><span class="cls_004">other cases, we use String Interpolation to build up the full file path of the relevant image</span></div>
<div style="position:absolute;left:5.00px;top:697.50px" class="cls_004"><span class="cls_004">and then return it from the converter as the converted value. As the </span><span class="cls_007">ConvertBack</span><span class="cls_004"> method in</span></div>
<div style="position:absolute;left:5.00px;top:715.50px" class="cls_004"><span class="cls_004">this converter has no valid use, it is not implemented and simply returns the</span></div>
<div style="position:absolute;left:5.00px;top:733.50px" class="cls_007"><span class="cls_007">DependencyProperty.UnsetValue</span><span class="cls_004"> value.</span></div>
<div style="position:absolute;left:5.00px;top:751.50px" class="cls_004"><span class="cls_004">You may have noticed that we specified the </span><span class="cls_007">ImageSource</span><span class="cls_004"> type in the </span><span class="cls_007">ValueConversion</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:65764px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background084.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">attribute, but we returned a string. This is possible because XAML uses the relevant type</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">converter to convert the string into an </span><span class="cls_007">ImageSource</span><span class="cls_004"> object automatically for us. Exactly the</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">same thing occurs when we set an </span><span class="cls_007">Image.Source</span><span class="cls_004"> property with a string in XAML.</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">As with other parts of our framework, we can make our converters even more useful, when</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">we combine functionality from other areas. In this particular example, we utilize one of the</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">Extension methods that was shown earlier in this chapter. To remind you, the</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_007"><span class="cls_007">GetDescription</span><span class="cls_004"> method will return the value of the </span><span class="cls_007">DescriptionAttribute</span><span class="cls_004"> that is set on</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">each enumeration instance.</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">DescriptionAttribute</span><span class="cls_004"> enables us to associate any string value with each of our</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">enumeration instances, so this is a great way to output a user friendly description for each</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">instance. An example of this would be as follows:</span></div>
<div style="position:absolute;left:52.98px;top:207.00px" class="cls_007"><span class="cls_007">public enum BitRate</span></div>
<div style="position:absolute;left:52.98px;top:220.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:234.00px" class="cls_007"><span class="cls_007">[Description("16 bits")]</span></div>
<div style="position:absolute;left:67.97px;top:247.50px" class="cls_007"><span class="cls_007">Sixteen = 16,</span></div>
<div style="position:absolute;left:67.97px;top:261.00px" class="cls_007"><span class="cls_007">[Description("24 bits")]</span></div>
<div style="position:absolute;left:67.97px;top:274.50px" class="cls_007"><span class="cls_007">TwentyFour = 24,</span></div>
<div style="position:absolute;left:67.97px;top:288.00px" class="cls_007"><span class="cls_007">[Description("32 bits")]</span></div>
<div style="position:absolute;left:67.97px;top:301.50px" class="cls_007"><span class="cls_007">ThirtyTwo = 32,</span></div>
<div style="position:absolute;left:52.98px;top:315.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:335.25px" class="cls_004"><span class="cls_004">In this way, instead of displaying the names of the instances in a </span><span class="cls_007">RadioButton</span><span class="cls_004"> control for</span></div>
<div style="position:absolute;left:5.00px;top:353.25px" class="cls_004"><span class="cls_004">example, we could display the more humanized descriptions from these attributes. Let's</span></div>
<div style="position:absolute;left:5.00px;top:371.25px" class="cls_004"><span class="cls_004">have a look at this converter class now.</span></div>
<div style="position:absolute;left:52.98px;top:394.50px" class="cls_007"><span class="cls_007">using System;</span></div>
<div style="position:absolute;left:52.98px;top:408.00px" class="cls_007"><span class="cls_007">using System.Globalization;</span></div>
<div style="position:absolute;left:52.98px;top:421.50px" class="cls_007"><span class="cls_007">using System.Windows;</span></div>
<div style="position:absolute;left:52.98px;top:435.00px" class="cls_007"><span class="cls_007">using System.Windows.Data;</span></div>
<div style="position:absolute;left:52.98px;top:448.50px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.Extensions;</span></div>
<div style="position:absolute;left:52.98px;top:475.50px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.Converters</span></div>
<div style="position:absolute;left:52.98px;top:489.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:502.50px" class="cls_007"><span class="cls_007">[ValueConversion(typeof(Enum), typeof(string))]</span></div>
<div style="position:absolute;left:67.97px;top:516.00px" class="cls_007"><span class="cls_007">public class EnumToDescriptionStringConverter : IValueConverter</span></div>
<div style="position:absolute;left:67.97px;top:529.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:543.00px" class="cls_007"><span class="cls_007">public object Convert(object value, Type targetType,</span></div>
<div style="position:absolute;left:97.96px;top:556.50px" class="cls_007"><span class="cls_007">object parameter, CultureInfo culture)</span></div>
<div style="position:absolute;left:82.97px;top:570.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:583.50px" class="cls_007"><span class="cls_007">if (value == null || (value.GetType() != typeof(Enum) &&</span></div>
<div style="position:absolute;left:112.96px;top:597.00px" class="cls_007"><span class="cls_007">value.GetType().BaseType != typeof(Enum)))</span></div>
<div style="position:absolute;left:112.96px;top:610.50px" class="cls_007"><span class="cls_007">return DependencyProperty.UnsetValue;</span></div>
<div style="position:absolute;left:97.96px;top:624.00px" class="cls_007"><span class="cls_007">Enum enumInstance = (Enum)value;</span></div>
<div style="position:absolute;left:97.96px;top:637.50px" class="cls_007"><span class="cls_007">return enumInstance.GetDescription();</span></div>
<div style="position:absolute;left:82.97px;top:651.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:678.00px" class="cls_007"><span class="cls_007">public object ConvertBack(object value, Type targetType,</span></div>
<div style="position:absolute;left:97.96px;top:691.50px" class="cls_007"><span class="cls_007">object parameter, CultureInfo culture)</span></div>
<div style="position:absolute;left:82.97px;top:705.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:718.50px" class="cls_007"><span class="cls_007">return DependencyProperty.UnsetValue;</span></div>
<div style="position:absolute;left:82.97px;top:732.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:745.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:759.00px" class="cls_007"><span class="cls_007">}</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:66566px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background085.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">As we're now accustomed to doing, we start by specifying the data types used in the</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">converter in the </span><span class="cls_007">ValueConversion</span><span class="cls_004"> attribute. In the </span><span class="cls_007">Convert</span><span class="cls_004"> method, we again check the</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">validity of our </span><span class="cls_007">value</span><span class="cls_004"> input parameter and return the </span><span class="cls_007">DependencyProperty.UnsetValue</span><span class="cls_004"> value</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">if it is invalid.</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">If it is valid, we cast it to a </span><span class="cls_007">Enum</span><span class="cls_004"> instance and then use the power of our Extension method</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">to return the value from each instance's </span><span class="cls_007">DescriptionAttribute</span><span class="cls_004">. In doing so, we are able to</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">expose this functionality to our Views and to enable the users of our framework to utilize it</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">directly from the XAML. Now that we have a general understanding of the various ways that</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">we can encapsulate functionality into our framework, let's focus on starting construction of</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">our base classes.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:67368px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background086.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_008"><span class="cls_008">Constructing a custom application</span></div>
<div style="position:absolute;left:5.00px;top:39.01px" class="cls_008"><span class="cls_008">framework</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">There will be different requirements for different components, but typically, the properties</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">and functionality that we build into our Data Model base classes will be utilized and made</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">more useful by our other base classes, so let's start by looking at the various Data Model</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">base classes first.</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">One thing that we need to decide is whether we want any of our Data Model base classes</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">to be generic or not. The difference can be subtle, but important. Imagine that we want to</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">add some basic undo functionality into a base class. One way that we can achieve this</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">would be to add an object into the base class that represents the unedited version of the</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">Data Model. In an ordinary base class, it would look like this:</span></div>
<div style="position:absolute;left:52.98px;top:243.00px" class="cls_007"><span class="cls_007">private object originalState;</span></div>
<div style="position:absolute;left:52.98px;top:270.00px" class="cls_007"><span class="cls_007">public object OriginalState</span></div>
<div style="position:absolute;left:52.98px;top:283.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:297.00px" class="cls_007"><span class="cls_007">get { return originalState; }</span></div>
<div style="position:absolute;left:67.97px;top:310.50px" class="cls_007"><span class="cls_007">private set { originalState = value; }</span></div>
<div style="position:absolute;left:52.98px;top:324.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:344.25px" class="cls_004"><span class="cls_004">In a generic base class, it would look like this:</span></div>
<div style="position:absolute;left:52.98px;top:367.50px" class="cls_007"><span class="cls_007">public abstract class BaseSynchronizableDataModel<T> :</span></div>
<div style="position:absolute;left:52.98px;top:381.00px" class="cls_007"><span class="cls_007">BaseDataModel</span></div>
<div style="position:absolute;left:52.98px;top:394.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:408.00px" class="cls_007"><span class="cls_007">private T originalState;</span></div>
<div style="position:absolute;left:67.97px;top:435.00px" class="cls_007"><span class="cls_007">public T OriginalState</span></div>
<div style="position:absolute;left:67.97px;top:448.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:462.00px" class="cls_007"><span class="cls_007">get { return originalState; }</span></div>
<div style="position:absolute;left:82.97px;top:475.50px" class="cls_007"><span class="cls_007">private set { originalState = value; }</span></div>
<div style="position:absolute;left:67.97px;top:489.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:502.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:522.75px" class="cls_004"><span class="cls_004">To make this property more useful, we'll need to add some further methods. First, we'll see</span></div>
<div style="position:absolute;left:5.00px;top:540.75px" class="cls_004"><span class="cls_004">the non-generic versions.</span></div>
<div style="position:absolute;left:52.98px;top:564.00px" class="cls_007"><span class="cls_007">public abstract void CopyValuesFrom(object dataModel);</span></div>
<div style="position:absolute;left:52.98px;top:591.00px" class="cls_007"><span class="cls_007">public virtual object Clone()</span></div>
<div style="position:absolute;left:52.98px;top:604.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:618.00px" class="cls_007"><span class="cls_007">object clone = new object();</span></div>
<div style="position:absolute;left:67.97px;top:631.50px" class="cls_007"><span class="cls_007">clone.CopyValuesFrom(this);</span></div>
<div style="position:absolute;left:67.97px;top:645.00px" class="cls_007"><span class="cls_007">return clone;</span></div>
<div style="position:absolute;left:52.98px;top:658.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:685.50px" class="cls_007"><span class="cls_007">public abstract bool PropertiesEqual(object dataModel);</span></div>
<div style="position:absolute;left:5.00px;top:705.75px" class="cls_004"><span class="cls_004">Now let's look at the generic versions:</span></div>
<div style="position:absolute;left:52.98px;top:729.00px" class="cls_007"><span class="cls_007">public abstract void CopyValuesFrom(T dataModel);</span></div>
<div style="position:absolute;left:52.98px;top:756.00px" class="cls_007"><span class="cls_007">public virtual T Clone()</span></div>
<div style="position:absolute;left:52.98px;top:769.50px" class="cls_007"><span class="cls_007">{</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:68170px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background087.jpg" width=612 height=792></div>
<div style="position:absolute;left:67.97px;top:3.00px" class="cls_007"><span class="cls_007">T clone = new T();</span></div>
<div style="position:absolute;left:67.97px;top:16.50px" class="cls_007"><span class="cls_007">clone.CopyValuesFrom(this as T);</span></div>
<div style="position:absolute;left:67.97px;top:30.00px" class="cls_007"><span class="cls_007">return clone;</span></div>
<div style="position:absolute;left:52.98px;top:43.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:70.50px" class="cls_007"><span class="cls_007">public abstract bool PropertiesEqual(T dataModel);</span></div>
<div style="position:absolute;left:5.00px;top:90.75px" class="cls_004"><span class="cls_004">The last few members of this base class would be the same for both versions.</span></div>
<div style="position:absolute;left:52.98px;top:114.00px" class="cls_007"><span class="cls_007">public bool HasChanges</span></div>
<div style="position:absolute;left:52.98px;top:127.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:141.00px" class="cls_007"><span class="cls_007">get { return originalState != null &&</span></div>
<div style="position:absolute;left:52.98px;top:154.50px" class="cls_007"><span class="cls_007">!PropertiesEqual(originalState); }</span></div>
<div style="position:absolute;left:52.98px;top:168.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:195.00px" class="cls_007"><span class="cls_007">public void Synchronize()</span></div>
<div style="position:absolute;left:52.98px;top:208.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:222.00px" class="cls_007"><span class="cls_007">originalState = this.Clone();</span></div>
<div style="position:absolute;left:67.97px;top:235.50px" class="cls_007"><span class="cls_007">NotifyPropertyChanged(nameof(HasChanges));</span></div>
<div style="position:absolute;left:52.98px;top:249.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:276.00px" class="cls_007"><span class="cls_007">public void RevertState()</span></div>
<div style="position:absolute;left:52.98px;top:289.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:303.00px" class="cls_007"><span class="cls_007">Debug.Assert(originalState != null, "Object not yet</span></div>
<div style="position:absolute;left:52.98px;top:316.50px" class="cls_007"><span class="cls_007">synchronized.");</span></div>
<div style="position:absolute;left:67.97px;top:330.00px" class="cls_007"><span class="cls_007">CopyValuesFrom(originalState);</span></div>
<div style="position:absolute;left:67.97px;top:343.50px" class="cls_007"><span class="cls_007">Synchronize();</span></div>
<div style="position:absolute;left:67.97px;top:357.00px" class="cls_007"><span class="cls_007">NotifyPropertyChanged(nameof(HasChanges));</span></div>
<div style="position:absolute;left:52.98px;top:370.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:390.75px" class="cls_004"><span class="cls_004">We started with the </span><span class="cls_007">OriginalState</span><span class="cls_004"> property which holds the unedited version of the Data</span></div>
<div style="position:absolute;left:5.00px;top:408.75px" class="cls_004"><span class="cls_004">Model. After that, we see the abstract </span><span class="cls_007">CopyValuesFrom</span><span class="cls_004"> method that the developers will</span></div>
<div style="position:absolute;left:5.00px;top:426.75px" class="cls_004"><span class="cls_004">need to implement and we'll see an example of that implementation shortly. The </span><span class="cls_007">Clone</span></div>
<div style="position:absolute;left:5.00px;top:444.75px" class="cls_004"><span class="cls_004">method simply calls the </span><span class="cls_007">CopyValuesFrom</span><span class="cls_004"> method in order to perform a deep clone of the</span></div>
<div style="position:absolute;left:5.00px;top:462.75px" class="cls_004"><span class="cls_004">Data Model.</span></div>
<div style="position:absolute;left:5.00px;top:480.75px" class="cls_004"><span class="cls_004">Next, we have the abstract </span><span class="cls_007">PropertiesEqual</span><span class="cls_004"> method that the developers will need to</span></div>
<div style="position:absolute;left:5.00px;top:498.75px" class="cls_004"><span class="cls_004">implement in order to compare each property in their classes with those from the </span><span class="cls_007">dataModel</span></div>
<div style="position:absolute;left:5.00px;top:516.75px" class="cls_004"><span class="cls_004">input parameter. Again, we'll see this implementation shortly, but you may be wondering</span></div>
<div style="position:absolute;left:5.00px;top:534.75px" class="cls_004"><span class="cls_004">why we don't just override the </span><span class="cls_007">Equals</span><span class="cls_004"> method, or implement the </span><span class="cls_007">IEquatable.Equals</span><span class="cls_004"> method</span></div>
<div style="position:absolute;left:5.00px;top:552.75px" class="cls_004"><span class="cls_004">for this purpose.</span></div>
<div style="position:absolute;left:5.00px;top:570.75px" class="cls_004"><span class="cls_004">The reason why we don't want to use either of those methods is because they, along with</span></div>
<div style="position:absolute;left:5.00px;top:588.75px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">GetHashCode</span><span class="cls_004"> method, are used by the WPF Framework in various places and they</span></div>
<div style="position:absolute;left:5.00px;top:606.75px" class="cls_004"><span class="cls_004">expect the returned values to be immutable. As our object's properties are very much</span></div>
<div style="position:absolute;left:5.00px;top:624.75px" class="cls_004"><span class="cls_004">mutable, they cannot be used to return the values for those methods. Therefore, we have</span></div>
<div style="position:absolute;left:5.00px;top:642.75px" class="cls_004"><span class="cls_004">implemented our own version. Let's return to the description of the remainder of this code.</span></div>
<div style="position:absolute;left:5.00px;top:660.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">HasChanges</span><span class="cls_004"> property is the property that we would want to data bind to a UI control to</span></div>
<div style="position:absolute;left:5.00px;top:678.75px" class="cls_004"><span class="cls_004">indicate whether a particular object had been edited or not. The </span><span class="cls_007">Synchronize</span><span class="cls_004"> method sets a</span></div>
<div style="position:absolute;left:5.00px;top:696.75px" class="cls_004"><span class="cls_004">deep clone of the current Data Model to the </span><span class="cls_007">originalState</span><span class="cls_004"> field and importantly, notifies</span></div>
<div style="position:absolute;left:5.00px;top:714.75px" class="cls_004"><span class="cls_004">the WPF Framework of a change to the </span><span class="cls_007">HasChanges</span><span class="cls_004"> property. This is done because the</span></div>
<div style="position:absolute;left:5.00px;top:732.75px" class="cls_007"><span class="cls_007">HasChanges</span><span class="cls_004"> property has no setter of its own and this operation will affect its value.</span></div>
<div style="position:absolute;left:5.00px;top:750.75px" class="cls_004"><span class="cls_004">It is very important that we set a cloned version to the </span><span class="cls_007">originalState</span><span class="cls_004"> field, rather than</span></div>
<div style="position:absolute;left:5.00px;top:768.75px" class="cls_004"><span class="cls_004">simply assigning the actual object reference to it. This is because we need to have a</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:68972px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background088.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">completely separate version of this object to represent the unedited version of the Data</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">Model. If we simply assigned the actual object reference to the </span><span class="cls_007">originalState</span><span class="cls_004"> field, then</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">its property values would change along with the Data Model object and render it useless for</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">this feature.</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">RevertState</span><span class="cls_004"> method first checks that the Data Model has been synchronized and then</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">copies the values back from the </span><span class="cls_007">originalState</span><span class="cls_004"> field to the model. Finally, it calls the</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_007"><span class="cls_007">Synchronize</span><span class="cls_004"> method to specify that this is the new, unedited version of the object and</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">notifies the WPF Framework of a change to the </span><span class="cls_007">HasChanges</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">So, as you can see, there are not many differences between these two versions of the</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">base class. In fact, the differences can be seen more clearly in the implementation of the</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">derived classes. Let's now focus on their implementations of the example abstract methods,</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">starting with the non-generic versions.</span></div>
<div style="position:absolute;left:52.98px;top:225.00px" class="cls_007"><span class="cls_007">public override bool PropertiesEqual(object genreObject)</span></div>
<div style="position:absolute;left:52.98px;top:238.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:252.00px" class="cls_007"><span class="cls_007">if (genreObject.GetType() != typeof(Genre)) return false;</span></div>
<div style="position:absolute;left:67.97px;top:265.50px" class="cls_007"><span class="cls_007">Genre genre = (Genre)genreObject;</span></div>
<div style="position:absolute;left:67.97px;top:279.00px" class="cls_007"><span class="cls_007">return Name == genre.Name && Description == genre.Description;</span></div>
<div style="position:absolute;left:52.98px;top:292.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:319.50px" class="cls_007"><span class="cls_007">public override void CopyValuesFrom(object genreObject)</span></div>
<div style="position:absolute;left:52.98px;top:333.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:346.50px" class="cls_007"><span class="cls_007">Debug.Assert(genreObject.GetType() == typeof(Genre), "You are</span></div>
<div style="position:absolute;left:52.98px;top:360.00px" class="cls_007"><span class="cls_007">using</span></div>
<div style="position:absolute;left:82.97px;top:373.50px" class="cls_007"><span class="cls_007">the wrong type with this method.");</span></div>
<div style="position:absolute;left:67.97px;top:387.00px" class="cls_007"><span class="cls_007">Genre genre = (Genre)genreObject;</span></div>
<div style="position:absolute;left:67.97px;top:400.50px" class="cls_007"><span class="cls_007">Name = genre.Name;</span></div>
<div style="position:absolute;left:67.97px;top:414.00px" class="cls_007"><span class="cls_007">Description = genre.Description;</span></div>
<div style="position:absolute;left:52.98px;top:427.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:447.75px" class="cls_004"><span class="cls_004">Before discussing this code, let's first see the generic implementations.</span></div>
<div style="position:absolute;left:52.98px;top:471.00px" class="cls_007"><span class="cls_007">public override bool PropertiesEqual(Genre genre)</span></div>
<div style="position:absolute;left:52.98px;top:484.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:498.00px" class="cls_007"><span class="cls_007">return Name == genre.Name && Description == genre.Description;</span></div>
<div style="position:absolute;left:52.98px;top:511.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:538.50px" class="cls_007"><span class="cls_007">public override void CopyValuesFrom(Genre genre)</span></div>
<div style="position:absolute;left:52.98px;top:552.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:565.50px" class="cls_007"><span class="cls_007">Name = genre.Name;</span></div>
<div style="position:absolute;left:67.97px;top:579.00px" class="cls_007"><span class="cls_007">Description = genre.Description;</span></div>
<div style="position:absolute;left:52.98px;top:592.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:612.75px" class="cls_004"><span class="cls_004">At last, we can see the difference between using generic and non-generic base classes.</span></div>
<div style="position:absolute;left:5.00px;top:630.75px" class="cls_004"><span class="cls_004">Without using generics, we have to use </span><span class="cls_007">object</span><span class="cls_004"> input parameters, which will need to be cast</span></div>
<div style="position:absolute;left:5.00px;top:648.75px" class="cls_004"><span class="cls_004">to the appropriate type in each of the derived classes before we can access their</span></div>
<div style="position:absolute;left:5.00px;top:666.75px" class="cls_004"><span class="cls_004">properties. Attempting to cast inappropriate types causes Exceptions, so we generally try</span></div>
<div style="position:absolute;left:5.00px;top:684.75px" class="cls_004"><span class="cls_004">to avoid these situations.</span></div>
<div style="position:absolute;left:5.00px;top:702.75px" class="cls_004"><span class="cls_004">On the other hand, when using a generic base class, there is no need to cast, as the input</span></div>
<div style="position:absolute;left:5.00px;top:720.75px" class="cls_004"><span class="cls_004">parameters are already of the correct type. In short, generics enable us to create type-safe</span></div>
<div style="position:absolute;left:5.00px;top:738.75px" class="cls_004"><span class="cls_004">data models and avoid duplicating type specific code. Now that we have seen the benefit of</span></div>
<div style="position:absolute;left:5.00px;top:756.75px" class="cls_004"><span class="cls_004">using generic classes, let's take a pause from generics for a moment and look at this base</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:69774px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background089.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">class a bit closer.</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">Some of you may have noticed that the only places where the WPF Framework is notified</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">of changes to our </span><span class="cls_007">HasChanges</span><span class="cls_004"> property is in the </span><span class="cls_007">Synchronize</span><span class="cls_004"> and </span><span class="cls_007">RevertState</span><span class="cls_004"> methods.</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">However, in order for this functionality to work properly, we need to notify the Framework</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">every time the values of any properties are changed.</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">We could rely on the developers to call the </span><span class="cls_007">NotifyPropertyChanged</span><span class="cls_004"> method, passing the</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_007"><span class="cls_007">HasChanges</span><span class="cls_004"> property name each time they call it for each property that changes, but if they</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">forgot to do this, it could lead to errors that could be difficult for them to track down.</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">Instead, a better solution would be for us to override the default implementation of the</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_007"><span class="cls_007">INotifyPropertyChanged</span><span class="cls_004"> interface from the base class and notify changes to the</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_007"><span class="cls_007">HasChanges</span><span class="cls_004"> property for them each time it is called.</span></div>
<div style="position:absolute;left:52.98px;top:207.00px" class="cls_007"><span class="cls_007">#region INotifyPropertyChanged Members</span></div>
<div style="position:absolute;left:52.98px;top:234.00px" class="cls_007"><span class="cls_007">protected override void NotifyPropertyChanged(</span></div>
<div style="position:absolute;left:67.97px;top:247.50px" class="cls_007"><span class="cls_007">params string[] propertyNames)</span></div>
<div style="position:absolute;left:52.98px;top:261.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:274.50px" class="cls_007"><span class="cls_007">if (PropertyChanged != null)</span></div>
<div style="position:absolute;left:67.97px;top:288.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:301.50px" class="cls_007"><span class="cls_007">foreach (string propertyName in propertyNames)</span></div>
<div style="position:absolute;left:82.97px;top:315.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:328.50px" class="cls_007"><span class="cls_007">if (propertyName != nameof(HasChanges)) PropertyChanged(this,</span></div>
<div style="position:absolute;left:112.96px;top:342.00px" class="cls_007"><span class="cls_007">new PropertyChangedEventArgs(propertyName));</span></div>
<div style="position:absolute;left:82.97px;top:355.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:369.00px" class="cls_007"><span class="cls_007">PropertyChanged(this,</span></div>
<div style="position:absolute;left:97.96px;top:382.50px" class="cls_007"><span class="cls_007">new PropertyChangedEventArgs(nameof(HasChanges)));</span></div>
<div style="position:absolute;left:67.97px;top:396.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:409.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:436.50px" class="cls_007"><span class="cls_007">protected override void NotifyPropertyChanged(</span></div>
<div style="position:absolute;left:67.97px;top:450.00px" class="cls_007"><span class="cls_007">[CallerMemberName]string propertyName = "")</span></div>
<div style="position:absolute;left:52.98px;top:463.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:477.00px" class="cls_007"><span class="cls_007">if (PropertyChanged != null)</span></div>
<div style="position:absolute;left:67.97px;top:490.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:504.00px" class="cls_007"><span class="cls_007">if (propertyName != nameof(HasChanges)) PropertyChanged(this,</span></div>
<div style="position:absolute;left:97.96px;top:517.50px" class="cls_007"><span class="cls_007">new PropertyChangedEventArgs(propertyName));</span></div>
<div style="position:absolute;left:82.97px;top:531.00px" class="cls_007"><span class="cls_007">PropertyChanged(this,</span></div>
<div style="position:absolute;left:97.96px;top:544.50px" class="cls_007"><span class="cls_007">new PropertyChangedEventArgs(nameof(HasChanges)));</span></div>
<div style="position:absolute;left:67.97px;top:558.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:571.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:598.50px" class="cls_007"><span class="cls_007">#endregion</span></div>
<div style="position:absolute;left:5.00px;top:631.50px" class="cls_004"><span class="cls_004">The first method will raise the </span><span class="cls_007">PropertyChanged</span><span class="cls_004"> event, passing the name of the </span><span class="cls_007">HasChanges</span></div>
<div style="position:absolute;left:5.00px;top:649.50px" class="cls_004"><span class="cls_004">property just once, regardless of how many property names were passed to the method.</span></div>
<div style="position:absolute;left:5.00px;top:667.50px" class="cls_004"><span class="cls_004">The second method also performs a check to ensure that it will refrain from raising the</span></div>
<div style="position:absolute;left:5.00px;top:685.50px" class="cls_004"><span class="cls_004">event with the </span><span class="cls_007">HasChanges</span><span class="cls_004"> property name more than once, so these implementations remain</span></div>
<div style="position:absolute;left:5.00px;top:703.50px" class="cls_004"><span class="cls_004">efficient.</span></div>
<div style="position:absolute;left:5.00px;top:721.50px" class="cls_004"><span class="cls_004">Now our base class will work as expected and the </span><span class="cls_007">HasChanges</span><span class="cls_004"> property will correctly</span></div>
<div style="position:absolute;left:5.00px;top:739.50px" class="cls_004"><span class="cls_004">update when other properties in the Data Model classes are changed. This technique can</span></div>
<div style="position:absolute;left:5.00px;top:757.50px" class="cls_004"><span class="cls_004">also be utilized in other scenarios, for example, when validating our property values, as we'll</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:70576px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background090.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">see later in </span><span class="cls_015">Chapter 8</span><span class="cls_004">, </span><span class="cls_006">Implementing Responsive Data Validation</span><span class="cls_004">. For now though, let's</span></div>
<div style="position:absolute;left:5.00px;top:22.50px" class="cls_004"><span class="cls_004">return to see what else we can achieve with generics.</span></div>
<div style="position:absolute;left:5.00px;top:40.50px" class="cls_004"><span class="cls_004">Another area where generics are often used relates to collections. I'm sure that you're all</span></div>
<div style="position:absolute;left:5.00px;top:58.50px" class="cls_004"><span class="cls_004">aware that we tend to use the </span><span class="cls_007">ObservableCollection<T></span><span class="cls_004"> class in WPF applications,</span></div>
<div style="position:absolute;left:5.00px;top:76.50px" class="cls_004"><span class="cls_004">because of its </span><span class="cls_007">INotifyCollectionChanged</span><span class="cls_004"> and </span><span class="cls_007">INotifyPropertyChanged</span><span class="cls_004"> implementations.</span></div>
<div style="position:absolute;left:5.00px;top:94.50px" class="cls_004"><span class="cls_004">It is customary, but not essential, to extend this class for each type of Data Model class</span></div>
<div style="position:absolute;left:5.00px;top:112.50px" class="cls_004"><span class="cls_004">that we have.</span></div>
<div style="position:absolute;left:52.98px;top:135.75px" class="cls_007"><span class="cls_007">public class Users : ObservableCollection<User></span></div>
<div style="position:absolute;left:5.00px;top:156.00px" class="cls_004"><span class="cls_004">However, instead of doing this, we can declare a </span><span class="cls_007">BaseCollection<T></span><span class="cls_004"> class that extends the</span></div>
<div style="position:absolute;left:5.00px;top:174.00px" class="cls_007"><span class="cls_007">ObservableCollection<T></span><span class="cls_004"> class and adds further functionality into our framework for us.</span></div>
<div style="position:absolute;left:5.00px;top:192.00px" class="cls_004"><span class="cls_004">The users of our framework can then extend this class instead.</span></div>
<div style="position:absolute;left:52.98px;top:215.25px" class="cls_007"><span class="cls_007">public class Users : BaseCollection<User></span></div>
<div style="position:absolute;left:5.00px;top:235.50px" class="cls_004"><span class="cls_004">One really useful thing that we can do is to add a generic property of type </span><span class="cls_007">T</span><span class="cls_004"> into our base</span></div>
<div style="position:absolute;left:5.00px;top:253.50px" class="cls_004"><span class="cls_004">class, that will represent the currently selected item in a data bound collection control in the</span></div>
<div style="position:absolute;left:5.00px;top:271.50px" class="cls_004"><span class="cls_004">UI. We could also declare some delegates to notify developers of changes to either</span></div>
<div style="position:absolute;left:5.00px;top:289.50px" class="cls_004"><span class="cls_004">selection or property values. There are so many short cuts and helper methods that we can</span></div>
<div style="position:absolute;left:5.00px;top:307.50px" class="cls_004"><span class="cls_004">provide here, dependent on requirements, so it's worth spending some time investigating</span></div>
<div style="position:absolute;left:5.00px;top:325.50px" class="cls_004"><span class="cls_004">this. Let's take a look a few possibilities.</span></div>
<div style="position:absolute;left:52.98px;top:348.75px" class="cls_007"><span class="cls_007">using System.Collections.Generic;</span></div>
<div style="position:absolute;left:52.98px;top:362.25px" class="cls_007"><span class="cls_007">using System.Collections.ObjectModel;</span></div>
<div style="position:absolute;left:52.98px;top:375.75px" class="cls_007"><span class="cls_007">using System.ComponentModel;</span></div>
<div style="position:absolute;left:52.98px;top:389.25px" class="cls_007"><span class="cls_007">using System.Linq;</span></div>
<div style="position:absolute;left:52.98px;top:402.75px" class="cls_007"><span class="cls_007">using System.Runtime.CompilerServices;</span></div>
<div style="position:absolute;left:52.98px;top:416.25px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.Extensions;</span></div>
<div style="position:absolute;left:52.98px;top:443.25px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.DataModels.Collections</span></div>
<div style="position:absolute;left:52.98px;top:456.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:470.25px" class="cls_007"><span class="cls_007">public class BaseCollection<T> :</span></div>
<div style="position:absolute;left:82.97px;top:483.75px" class="cls_007"><span class="cls_007">ObservableCollection<T>, INotifyPropertyChanged</span></div>
<div style="position:absolute;left:82.97px;top:497.25px" class="cls_007"><span class="cls_007">where T : class, INotifyPropertyChanged, new()</span></div>
<div style="position:absolute;left:67.97px;top:510.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:524.25px" class="cls_007"><span class="cls_007">protected T currentItem;</span></div>
<div style="position:absolute;left:82.97px;top:551.25px" class="cls_007"><span class="cls_007">public BaseCollection(IEnumerable<T> collection) : this()</span></div>
<div style="position:absolute;left:82.97px;top:564.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:578.25px" class="cls_007"><span class="cls_007">foreach (T item in collection) Add(item);</span></div>
<div style="position:absolute;left:82.97px;top:591.75px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:618.75px" class="cls_007"><span class="cls_007">public BaseCollection(params T[] collection) :</span></div>
<div style="position:absolute;left:97.96px;top:632.25px" class="cls_007"><span class="cls_007">this(collection as IEnumerable<T>) { }</span></div>
<div style="position:absolute;left:82.97px;top:659.25px" class="cls_007"><span class="cls_007">public BaseCollection() : base()</span></div>
<div style="position:absolute;left:82.97px;top:672.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:686.25px" class="cls_007"><span class="cls_007">currentItem = new T();</span></div>
<div style="position:absolute;left:82.97px;top:699.75px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:726.75px" class="cls_007"><span class="cls_007">public virtual T CurrentItem</span></div>
<div style="position:absolute;left:82.97px;top:740.25px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:753.75px" class="cls_007"><span class="cls_007">get { return currentItem; }</span></div>
<div style="position:absolute;left:97.96px;top:767.25px" class="cls_007"><span class="cls_007">set</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:71378px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background091.jpg" width=612 height=792></div>
<div style="position:absolute;left:97.96px;top:3.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:112.96px;top:16.50px" class="cls_007"><span class="cls_007">T oldCurrentItem = currentItem;</span></div>
<div style="position:absolute;left:112.96px;top:30.00px" class="cls_007"><span class="cls_007">currentItem = value;</span></div>
<div style="position:absolute;left:112.96px;top:43.50px" class="cls_007"><span class="cls_007">CurrentItemChanged?.Invoke(oldCurrentItem, currentItem);</span></div>
<div style="position:absolute;left:112.96px;top:57.00px" class="cls_007"><span class="cls_007">NotifyPropertyChanged();</span></div>
<div style="position:absolute;left:97.96px;top:70.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:84.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:111.00px" class="cls_007"><span class="cls_007">public bool IsEmpty</span></div>
<div style="position:absolute;left:82.97px;top:124.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:138.00px" class="cls_007"><span class="cls_007">get { return !this.Any(); }</span></div>
<div style="position:absolute;left:82.97px;top:151.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:178.50px" class="cls_007"><span class="cls_007">public delegate void ItemPropertyChanged(T item,</span></div>
<div style="position:absolute;left:97.96px;top:192.00px" class="cls_007"><span class="cls_007">string propertyName);</span></div>
<div style="position:absolute;left:82.97px;top:219.00px" class="cls_007"><span class="cls_007">public virtual ItemPropertyChanged CurrentItemPropertyChanged</span></div>
<div style="position:absolute;left:97.96px;top:232.50px" class="cls_007"><span class="cls_007">{ get; set; }</span></div>
<div style="position:absolute;left:82.97px;top:259.50px" class="cls_007"><span class="cls_007">public delegate void CurrentItemChange(T oldItem, T newItem);</span></div>
<div style="position:absolute;left:82.97px;top:286.50px" class="cls_007"><span class="cls_007">public virtual CurrentItemChange CurrentItemChanged { get; set;</span></div>
<div style="position:absolute;left:52.98px;top:300.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:327.00px" class="cls_007"><span class="cls_007">public T GetNewItem()</span></div>
<div style="position:absolute;left:82.97px;top:340.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:354.00px" class="cls_007"><span class="cls_007">return new T();</span></div>
<div style="position:absolute;left:82.97px;top:367.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:394.50px" class="cls_007"><span class="cls_007">public virtual void AddEmptyItem()</span></div>
<div style="position:absolute;left:82.97px;top:408.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:421.50px" class="cls_007"><span class="cls_007">Add(new T());</span></div>
<div style="position:absolute;left:82.97px;top:435.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:462.00px" class="cls_007"><span class="cls_007">public virtual void Add(IEnumerable<T> collection)</span></div>
<div style="position:absolute;left:82.97px;top:475.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:489.00px" class="cls_007"><span class="cls_007">collection.ForEach(i => base.Add(i));</span></div>
<div style="position:absolute;left:82.97px;top:502.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:529.50px" class="cls_007"><span class="cls_007">public virtual void Add(params T[] items)</span></div>
<div style="position:absolute;left:82.97px;top:543.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:556.50px" class="cls_007"><span class="cls_007">if (items.Length == 1) base.Add(items[0]);</span></div>
<div style="position:absolute;left:97.96px;top:570.00px" class="cls_007"><span class="cls_007">else Add(items as IEnumerable<T>);</span></div>
<div style="position:absolute;left:82.97px;top:583.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:610.50px" class="cls_007"><span class="cls_007">protected override void InsertItem(int index, T item)</span></div>
<div style="position:absolute;left:82.97px;top:624.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:637.50px" class="cls_007"><span class="cls_007">if (item != null)</span></div>
<div style="position:absolute;left:97.96px;top:651.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:112.96px;top:664.50px" class="cls_007"><span class="cls_007">item.PropertyChanged += Item_PropertyChanged;</span></div>
<div style="position:absolute;left:112.96px;top:678.00px" class="cls_007"><span class="cls_007">base.InsertItem(index, item);</span></div>
<div style="position:absolute;left:112.96px;top:691.50px" class="cls_007"><span class="cls_007">if (Count == 1) CurrentItem = item;</span></div>
<div style="position:absolute;left:97.96px;top:705.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:718.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:745.50px" class="cls_007"><span class="cls_007">protected override void SetItem(int index, T item)</span></div>
<div style="position:absolute;left:82.97px;top:759.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:772.50px" class="cls_007"><span class="cls_007">if (item != null)</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:72180px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background092.jpg" width=612 height=792></div>
<div style="position:absolute;left:97.96px;top:3.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:112.96px;top:16.50px" class="cls_007"><span class="cls_007">item.PropertyChanged += Item_PropertyChanged;</span></div>
<div style="position:absolute;left:112.96px;top:30.00px" class="cls_007"><span class="cls_007">base.SetItem(index, item);</span></div>
<div style="position:absolute;left:112.96px;top:43.50px" class="cls_007"><span class="cls_007">if (Count == 1) CurrentItem = item;</span></div>
<div style="position:absolute;left:97.96px;top:57.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:70.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:97.50px" class="cls_007"><span class="cls_007">protected override void ClearItems()</span></div>
<div style="position:absolute;left:82.97px;top:111.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:124.50px" class="cls_007"><span class="cls_007">foreach (T item in this)</span></div>
<div style="position:absolute;left:112.96px;top:138.00px" class="cls_007"><span class="cls_007">item.PropertyChanged -= Item_PropertyChanged;</span></div>
<div style="position:absolute;left:97.96px;top:151.50px" class="cls_007"><span class="cls_007">base.ClearItems();</span></div>
<div style="position:absolute;left:82.97px;top:165.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:192.00px" class="cls_007"><span class="cls_007">protected override void RemoveItem(int index)</span></div>
<div style="position:absolute;left:82.97px;top:205.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:219.00px" class="cls_007"><span class="cls_007">T item = this[index];</span></div>
<div style="position:absolute;left:97.96px;top:232.50px" class="cls_007"><span class="cls_007">if (item != null) item.PropertyChanged -=</span></div>
<div style="position:absolute;left:52.98px;top:246.00px" class="cls_007"><span class="cls_007">Item_PropertyChanged;</span></div>
<div style="position:absolute;left:97.96px;top:259.50px" class="cls_007"><span class="cls_007">base.RemoveItem(index);</span></div>
<div style="position:absolute;left:82.97px;top:273.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:300.00px" class="cls_007"><span class="cls_007">public void ResetCurrentItemPosition()</span></div>
<div style="position:absolute;left:82.97px;top:313.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:327.00px" class="cls_007"><span class="cls_007">if (this.Any()) CurrentItem = this.First();</span></div>
<div style="position:absolute;left:82.97px;top:340.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:367.50px" class="cls_007"><span class="cls_007">private void Item_PropertyChanged(object sender,</span></div>
<div style="position:absolute;left:97.96px;top:381.00px" class="cls_007"><span class="cls_007">PropertyChangedEventArgs e)</span></div>
<div style="position:absolute;left:82.97px;top:394.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:408.00px" class="cls_007"><span class="cls_007">if ((sender as T) == CurrentItem)</span></div>
<div style="position:absolute;left:52.98px;top:421.50px" class="cls_007"><span class="cls_007">CurrentItemPropertyChanged?.</span></div>
<div style="position:absolute;left:112.96px;top:435.00px" class="cls_007"><span class="cls_007">Invoke(currentItem, e.PropertyName);</span></div>
<div style="position:absolute;left:97.96px;top:448.50px" class="cls_007"><span class="cls_007">NotifyPropertyChanged(e.PropertyName);</span></div>
<div style="position:absolute;left:82.97px;top:462.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:489.00px" class="cls_007"><span class="cls_007">#region INotifyPropertyChanged Members</span></div>
<div style="position:absolute;left:82.97px;top:543.00px" class="cls_007"><span class="cls_007">#endregion</span></div>
<div style="position:absolute;left:67.97px;top:556.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:570.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:590.25px" class="cls_004"><span class="cls_004">There's quite a lot to digest here, so let's go carefully over each part. We start with our</span></div>
<div style="position:absolute;left:5.00px;top:608.25px" class="cls_004"><span class="cls_004">private member of type </span><span class="cls_007">T</span><span class="cls_004"> that will back our </span><span class="cls_007">CurrentItem</span><span class="cls_004"> property. We then find a few</span></div>
<div style="position:absolute;left:5.00px;top:626.25px" class="cls_004"><span class="cls_004">overloads of the constructor that enable us to initialize our collection from either a collection,</span></div>
<div style="position:absolute;left:5.00px;top:644.25px" class="cls_004"><span class="cls_004">or any number of input parameters of the relevant type.</span></div>
<div style="position:absolute;left:5.00px;top:662.25px" class="cls_004"><span class="cls_004">Next, we see the </span><span class="cls_007">CurrentItem</span><span class="cls_004"> property from the </span><span class="cls_015">Chapter 1</span><span class="cls_004">, </span><span class="cls_006">A Smarter Way Of Working</span></div>
<div style="position:absolute;left:5.00px;top:681.00px" class="cls_006"><span class="cls_006">With WPF</span><span class="cls_004">, again, but now with some further context. If a class has subscribed to the</span></div>
<div style="position:absolute;left:5.00px;top:699.75px" class="cls_007"><span class="cls_007">CurrentItemChanged</span><span class="cls_004"> property, we will call the delegate from here, passing both the new</span></div>
<div style="position:absolute;left:5.00px;top:717.75px" class="cls_004"><span class="cls_004">and old values of the current item. The </span><span class="cls_007">IsEmpty</span><span class="cls_004"> property is just an efficient convenience</span></div>
<div style="position:absolute;left:5.00px;top:735.75px" class="cls_004"><span class="cls_004">property for our developers to call when they need to know whether the collection has any</span></div>
<div style="position:absolute;left:5.00px;top:753.75px" class="cls_004"><span class="cls_004">content or not.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:72982px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background093.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">After this, we see the collection delegates and the relevant property wrappers that enable</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">the developers that will use our framework to make use of them. Next, we see the</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">convenient </span><span class="cls_007">GetNewItem</span><span class="cls_004"> and </span><span class="cls_007">AddEmptyItem</span><span class="cls_004"> methods, which both generate a new item of the</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_007"><span class="cls_007">T</span><span class="cls_004"> generic type parameter, before returning or adding them to the collection respectively.</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">This is the reason that we needed to add the </span><span class="cls_007">new()</span><span class="cls_004"> generic type constraint to the class</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">definition; this type constraint specifies that the generic type used must have a</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">parameterless constructor.</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">And now we reach the various </span><span class="cls_007">Add</span><span class="cls_004"> methods of the collection; note that every way to add an</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">item to the collection must be handled, so that we can attach our </span><span class="cls_007">Item_PropertyChanged</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">handler to the </span><span class="cls_007">PropertyChanged</span><span class="cls_004"> event of each added item to ensure consistent behavior.</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">We therefore call our </span><span class="cls_007">Add</span><span class="cls_004"> methods from all other overloads and helper methods and call the</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">base </span><span class="cls_007">Collection.Add</span><span class="cls_004"> method from there. Note that we actually attach our handler inside</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">InsertItem</span><span class="cls_004"> method, as this overridden method is called from the </span><span class="cls_007">Add</span><span class="cls_004"> methods in the</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_007"><span class="cls_007">Collection</span><span class="cls_004"> class.</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">Likewise, the protected </span><span class="cls_007">SetItem</span><span class="cls_004"> method will be called by the </span><span class="cls_007">Collection</span><span class="cls_004"> class when items</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">are set using the index notation, so we must handle that too. Similarly, when items are</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">removed from the collection, it is equally, if not more, important to remove the reference to</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">our event handler from each object. Failing to do so can result in memory leaks, as the</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_004"><span class="cls_004">reference to the event handler can keep the Data Model objects from being disposed by the</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_004"><span class="cls_004">garbage collector.</span></div>
<div style="position:absolute;left:5.00px;top:363.75px" class="cls_004"><span class="cls_004">As such, we also need to handle every method of removing objects from our collection. To</span></div>
<div style="position:absolute;left:5.00px;top:381.75px" class="cls_004"><span class="cls_004">do this, we override a few more protected methods from the </span><span class="cls_007">Collection</span><span class="cls_004"> base class. The</span></div>
<div style="position:absolute;left:5.00px;top:399.75px" class="cls_007"><span class="cls_007">ClearItems</span><span class="cls_004"> method will be called internally when users call the </span><span class="cls_007">Clear</span><span class="cls_004"> method on our</span></div>
<div style="position:absolute;left:5.00px;top:417.75px" class="cls_004"><span class="cls_004">collection. Equally, the </span><span class="cls_007">RemoveItem</span><span class="cls_004"> method will be called when users call any of the public</span></div>
<div style="position:absolute;left:5.00px;top:435.75px" class="cls_004"><span class="cls_004">removal methods, so it is the optimal place to remove our handler.</span></div>
<div style="position:absolute;left:5.00px;top:453.75px" class="cls_004"><span class="cls_004">Skipping the </span><span class="cls_007">ResetCurrentItemPosition</span><span class="cls_004"> method for now, at the bottom of the class, we</span></div>
<div style="position:absolute;left:5.00px;top:471.75px" class="cls_004"><span class="cls_004">reach the </span><span class="cls_007">Item_PropertyChanged</span><span class="cls_004"> event handling method. If the item that has had the</span></div>
<div style="position:absolute;left:5.00px;top:489.75px" class="cls_004"><span class="cls_004">property changed is the current item in the collection, then we raise the</span></div>
<div style="position:absolute;left:5.00px;top:507.75px" class="cls_007"><span class="cls_007">ItemPropertyChanged</span><span class="cls_004"> delegate that is connected with the </span><span class="cls_007">CurrentItemPropertyChanged</span></div>
<div style="position:absolute;left:5.00px;top:525.75px" class="cls_004"><span class="cls_004">property.</span></div>
<div style="position:absolute;left:5.00px;top:543.75px" class="cls_004"><span class="cls_004">For every property change notification, regardless of whether the item is the current item or</span></div>
<div style="position:absolute;left:5.00px;top:561.75px" class="cls_004"><span class="cls_004">not, we then raise the </span><span class="cls_007">INotifyPropertyChanged.PropertyChanged</span><span class="cls_004"> event. This enables the</span></div>
<div style="position:absolute;left:5.00px;top:579.75px" class="cls_004"><span class="cls_004">developers that use our framework to be able to attach a handler to the </span><span class="cls_007">PropertyChanged</span></div>
<div style="position:absolute;left:5.00px;top:597.75px" class="cls_004"><span class="cls_004">event directly on our collections and be able to discover when any property has been</span></div>
<div style="position:absolute;left:5.00px;top:615.75px" class="cls_004"><span class="cls_004">changed on any of the items in the collection.</span></div>
<div style="position:absolute;left:5.00px;top:633.75px" class="cls_004"><span class="cls_004">You may also have noticed a few places in the collection class code where we set the value</span></div>
<div style="position:absolute;left:5.00px;top:651.75px" class="cls_004"><span class="cls_004">of the </span><span class="cls_007">CurrentItem</span><span class="cls_004"> property. The option chosen here is to always select the first item in the</span></div>
<div style="position:absolute;left:5.00px;top:669.75px" class="cls_004"><span class="cls_004">collection automatically, but it would be a simple change to have the last item selected</span></div>
<div style="position:absolute;left:5.00px;top:687.75px" class="cls_004"><span class="cls_004">instead, for example. As always, these kinds of details will depend on your specific</span></div>
<div style="position:absolute;left:5.00px;top:705.75px" class="cls_004"><span class="cls_004">requirements.</span></div>
<div style="position:absolute;left:5.00px;top:723.75px" class="cls_004"><span class="cls_004">Another benefit of declaring these base collection classes is that we can utilize the</span></div>
<div style="position:absolute;left:5.00px;top:741.75px" class="cls_004"><span class="cls_004">properties and extend the functionality that is built into our base Data Model classes.</span></div>
<div style="position:absolute;left:5.00px;top:759.75px" class="cls_004"><span class="cls_004">Thinking back to the simple example of our </span><span class="cls_007">BaseSynchronizableDataModel</span><span class="cls_004"> class, let's see</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:73784px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background094.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">what we could add into a new base collection class to improve this functionality.</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">Before we can do this however, we need to be able to specify that the objects in our new</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">collection have implemented the properties and methods from the</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_007"><span class="cls_007">BaseSynchronizableDataModel</span><span class="cls_004"> class. One option would be to declare our new collection</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">class like this:</span></div>
<div style="position:absolute;left:52.98px;top:99.00px" class="cls_007"><span class="cls_007">public class BaseSynchronizableCollection<T> : BaseCollection<T></span></div>
<div style="position:absolute;left:67.97px;top:112.50px" class="cls_007"><span class="cls_007">where T : BaseSynchronizableDataModel<T></span></div>
<div style="position:absolute;left:5.00px;top:132.75px" class="cls_004"><span class="cls_004">However, in C#, we can only extend a single base class, while we are free to implement as</span></div>
<div style="position:absolute;left:5.00px;top:150.75px" class="cls_004"><span class="cls_004">many interfaces as we like. A more preferable solution would therefore be for us to extract</span></div>
<div style="position:absolute;left:5.00px;top:168.75px" class="cls_004"><span class="cls_004">the relevant synchronization properties from our base class into an interface, add that to our</span></div>
<div style="position:absolute;left:5.00px;top:186.75px" class="cls_004"><span class="cls_004">base class definition.</span></div>
<div style="position:absolute;left:52.98px;top:210.00px" class="cls_007"><span class="cls_007">public abstract class BaseSynchronizableDataModel<T> :</span></div>
<div style="position:absolute;left:67.97px;top:223.50px" class="cls_007"><span class="cls_007">BaseDataModel, ISynchronizableDataModel<T></span></div>
<div style="position:absolute;left:67.97px;top:237.00px" class="cls_007"><span class="cls_007">where T : BaseDataModel, ISynchronizableDataModel<T>, new()</span></div>
<div style="position:absolute;left:5.00px;top:257.25px" class="cls_004"><span class="cls_004">We could then specify this new generic constraint on our new collection class like this:</span></div>
<div style="position:absolute;left:52.98px;top:280.50px" class="cls_007"><span class="cls_007">public class BaseSynchronizableCollection<T> : BaseCollection<T></span></div>
<div style="position:absolute;left:67.97px;top:294.00px" class="cls_007"><span class="cls_007">where T : class, ISynchronizableDataModel<T>, new()</span></div>
<div style="position:absolute;left:5.00px;top:314.25px" class="cls_004"><span class="cls_004">Note that any other generic constraints that are placed on the</span></div>
<div style="position:absolute;left:5.00px;top:332.25px" class="cls_007"><span class="cls_007">BaseSynchronizableDataModel</span><span class="cls_004"> class will also need to be added to the </span><span class="cls_007">where T</span><span class="cls_004"> part of this</span></div>
<div style="position:absolute;left:5.00px;top:350.25px" class="cls_004"><span class="cls_004">declaration. If for example, we needed to implement another interface in the base class and</span></div>
<div style="position:absolute;left:5.00px;top:368.25px" class="cls_004"><span class="cls_004">we did not add the same constraint for the </span><span class="cls_007">T</span><span class="cls_004"> generic type parameter in the base collection</span></div>
<div style="position:absolute;left:5.00px;top:386.25px" class="cls_004"><span class="cls_004">class, then we would get a compilation error when attempting to use instances of our base</span></div>
<div style="position:absolute;left:5.00px;top:404.25px" class="cls_004"><span class="cls_004">class as the </span><span class="cls_007">T</span><span class="cls_004"> parameter. Let's now look at this new base class:</span></div>
<div style="position:absolute;left:52.98px;top:427.50px" class="cls_007"><span class="cls_007">using System.Collections.Generic;</span></div>
<div style="position:absolute;left:52.98px;top:441.00px" class="cls_007"><span class="cls_007">using System.ComponentModel;</span></div>
<div style="position:absolute;left:52.98px;top:454.50px" class="cls_007"><span class="cls_007">using System.Linq;</span></div>
<div style="position:absolute;left:52.98px;top:468.00px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.DataModels.Interfaces;</span></div>
<div style="position:absolute;left:52.98px;top:481.50px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.Extensions;</span></div>
<div style="position:absolute;left:52.98px;top:508.50px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.DataModels.Collections</span></div>
<div style="position:absolute;left:52.98px;top:522.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:535.50px" class="cls_007"><span class="cls_007">public class BaseSynchronizableCollection<T> : BaseCollection<T></span></div>
<div style="position:absolute;left:82.97px;top:549.00px" class="cls_007"><span class="cls_007">where T : class, ISynchronizableDataModel<T>,</span></div>
<div style="position:absolute;left:82.97px;top:562.50px" class="cls_007"><span class="cls_007">INotifyPropertyChanged, new()</span></div>
<div style="position:absolute;left:67.97px;top:576.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:589.50px" class="cls_007"><span class="cls_007">public BaseSynchronizableCollection(IEnumerable<T> collection)</span></div>
<div style="position:absolute;left:52.98px;top:603.00px" class="cls_007"><span class="cls_007">:</span></div>
<div style="position:absolute;left:97.96px;top:616.50px" class="cls_007"><span class="cls_007">base(collection) { }</span></div>
<div style="position:absolute;left:82.97px;top:643.50px" class="cls_007"><span class="cls_007">public BaseSynchronizableCollection(params T[] collection) :</span></div>
<div style="position:absolute;left:97.96px;top:657.00px" class="cls_007"><span class="cls_007">base(collection as IEnumerable<T>) { }</span></div>
<div style="position:absolute;left:82.97px;top:684.00px" class="cls_007"><span class="cls_007">public BaseSynchronizableCollection() : base() { }</span></div>
<div style="position:absolute;left:82.97px;top:711.00px" class="cls_007"><span class="cls_007">public virtual bool HasChanges</span></div>
<div style="position:absolute;left:82.97px;top:724.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:738.00px" class="cls_007"><span class="cls_007">get { return this.Any(i => i.HasChanges); }</span></div>
<div style="position:absolute;left:82.97px;top:751.50px" class="cls_007"><span class="cls_007">}</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:74586px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background095.jpg" width=612 height=792></div>
<div style="position:absolute;left:82.97px;top:3.00px" class="cls_007"><span class="cls_007">public virtual bool AreSynchronized</span></div>
<div style="position:absolute;left:82.97px;top:16.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:30.00px" class="cls_007"><span class="cls_007">get { return this.All(i => i.IsSynchronized); }</span></div>
<div style="position:absolute;left:82.97px;top:43.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:70.50px" class="cls_007"><span class="cls_007">public virtual IEnumerable<T> ChangedCollection</span></div>
<div style="position:absolute;left:82.97px;top:84.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:97.50px" class="cls_007"><span class="cls_007">get { return this.Where(i => i.HasChanges); }</span></div>
<div style="position:absolute;left:82.97px;top:111.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:138.00px" class="cls_007"><span class="cls_007">public virtual void Synchronize()</span></div>
<div style="position:absolute;left:82.97px;top:151.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:165.00px" class="cls_007"><span class="cls_007">this.ForEach(i => i.Synchronize());</span></div>
<div style="position:absolute;left:82.97px;top:178.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:205.50px" class="cls_007"><span class="cls_007">public virtual void RevertState()</span></div>
<div style="position:absolute;left:82.97px;top:219.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:232.50px" class="cls_007"><span class="cls_007">this.ForEach(i => i.RevertState());</span></div>
<div style="position:absolute;left:82.97px;top:246.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:259.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:273.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:306.00px" class="cls_004"><span class="cls_004">While remaining simple, this base collection class provides some powerful functionality. We</span></div>
<div style="position:absolute;left:5.00px;top:324.00px" class="cls_004"><span class="cls_004">start off with the class declaration, with its generic type constraints that are inherited from</span></div>
<div style="position:absolute;left:5.00px;top:342.00px" class="cls_004"><span class="cls_004">both our target </span><span class="cls_007">T</span><span class="cls_004"> type classes and our </span><span class="cls_007">BaseCollection<T></span><span class="cls_004"> class. We've then implemented</span></div>
<div style="position:absolute;left:5.00px;top:360.00px" class="cls_004"><span class="cls_004">the constructor overloads and passed initialization duties straight to the base class.</span></div>
<div style="position:absolute;left:5.00px;top:378.00px" class="cls_004"><span class="cls_004">Note that had we wanted to attach an additional level of event handlers to our collection</span></div>
<div style="position:absolute;left:5.00px;top:396.00px" class="cls_004"><span class="cls_004">items, we would follow the pattern from the base class, rather than calling the base class</span></div>
<div style="position:absolute;left:5.00px;top:414.00px" class="cls_004"><span class="cls_004">constructors in this way.</span></div>
<div style="position:absolute;left:5.00px;top:432.00px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">HasChanges</span><span class="cls_004"> property can be used as a flag to detect whether any item in the collection</span></div>
<div style="position:absolute;left:5.00px;top:450.00px" class="cls_004"><span class="cls_004">has any changes or not. This would typically be tied to the </span><span class="cls_007">canExecute</span><span class="cls_004"> parameter of a save</span></div>
<div style="position:absolute;left:5.00px;top:468.00px" class="cls_004"><span class="cls_004">command, so that the save button would become enabled when any item in the collection</span></div>
<div style="position:absolute;left:5.00px;top:486.00px" class="cls_004"><span class="cls_004">had been edited and disabled if the changes were undone.</span></div>
<div style="position:absolute;left:5.00px;top:504.00px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">AreSynchronized</span><span class="cls_004"> property simply specifies whether the items in the collection have all</span></div>
<div style="position:absolute;left:5.00px;top:522.00px" class="cls_004"><span class="cls_004">been synchronized or not, but the real beauty of this class is in the </span><span class="cls_007">ChangedCollection</span></div>
<div style="position:absolute;left:5.00px;top:540.00px" class="cls_004"><span class="cls_004">property. Using a simple LINQ filter, we return only the items from the collection that have</span></div>
<div style="position:absolute;left:5.00px;top:558.00px" class="cls_004"><span class="cls_004">changes. Imagine a scenario where we enable the user to edit multiple items at once. With</span></div>
<div style="position:absolute;left:5.00px;top:576.00px" class="cls_004"><span class="cls_004">this property, our developers could extract just the items that they need to save from the</span></div>
<div style="position:absolute;left:5.00px;top:594.00px" class="cls_004"><span class="cls_004">collection with zero effort.</span></div>
<div style="position:absolute;left:5.00px;top:612.00px" class="cls_004"><span class="cls_004">Finally, this class provides one method to enable the synchronization of all of the items in</span></div>
<div style="position:absolute;left:5.00px;top:630.00px" class="cls_004"><span class="cls_004">the collection at once and another to undo the changes of all of the edited items in the</span></div>
<div style="position:absolute;left:5.00px;top:648.00px" class="cls_004"><span class="cls_004">collection likewise. Note the use of the custom </span><span class="cls_007">ForEach</span><span class="cls_004"> Extension method in these last two</span></div>
<div style="position:absolute;left:5.00px;top:666.00px" class="cls_004"><span class="cls_004">methods; if you remember from the earlier </span><span class="cls_006">With Extension methods</span><span class="cls_004"> section, it enables us</span></div>
<div style="position:absolute;left:5.00px;top:684.75px" class="cls_004"><span class="cls_004">to perform an action on each item in the collection.</span></div>
<div style="position:absolute;left:5.00px;top:702.75px" class="cls_004"><span class="cls_004">Through the use of the properties and methods of our Data Model base classes by other</span></div>
<div style="position:absolute;left:5.00px;top:720.75px" class="cls_004"><span class="cls_004">parts of our framework, we are able to extend their functionality further. While building</span></div>
<div style="position:absolute;left:5.00px;top:738.75px" class="cls_004"><span class="cls_004">composite functionality from different components in this way is generally optional, it can</span></div>
<div style="position:absolute;left:5.00px;top:756.75px" class="cls_004"><span class="cls_004">also be necessary, as we'll see later in the book.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:75388px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background096.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">The more common functionality that we can build into our application framework base</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">classes, the less work the developers that use our framework will have to do when</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">developing the application. However, we must plan carefully and not force the developers to</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">have unwanted properties and methods in order to extend a particular base class that has</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">some other functionality that they do want.</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">Typically, there will be different requirements for different components. The Data Model</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">classes will generally have more base classes than the View Models because they play a</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">bigger role than the View Models. The View Models simply provide the Views with the data</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">and functionality that they require. However, the Data Model contain that data, along with</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">validation, synchronization and possibly animation methods and properties. With this in</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">mind, let's look again at the View Model base class.</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">We have already seen that we will need an implementation of the </span><span class="cls_007">INotifyPropertyChanged</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">interface in our base class, but what else should we implement? If every View will be</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">providing some specific functionality, such as saving and deleting items for example, then</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">we can also add commands straight into our base class and abstract methods that each</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">derived View Model class will have to implement.</span></div>
<div style="position:absolute;left:52.98px;top:297.00px" class="cls_007"><span class="cls_007">public virtual ICommand Refresh</span></div>
<div style="position:absolute;left:52.98px;top:310.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:324.00px" class="cls_007"><span class="cls_007">get</span></div>
<div style="position:absolute;left:67.97px;top:337.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:351.00px" class="cls_007"><span class="cls_007">return new ActionCommand(action => RefreshData(),</span></div>
<div style="position:absolute;left:97.96px;top:364.50px" class="cls_007"><span class="cls_007">canExecute => CanRefreshData());</span></div>
<div style="position:absolute;left:67.97px;top:378.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:391.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:418.50px" class="cls_007"><span class="cls_007">protected abstract void RefreshData();</span></div>
<div style="position:absolute;left:52.98px;top:445.50px" class="cls_007"><span class="cls_007">protected abstract bool CanRefreshData();</span></div>
<div style="position:absolute;left:5.00px;top:465.75px" class="cls_004"><span class="cls_004">Again, it is important to declare this command as being virtual, in case the developers need</span></div>
<div style="position:absolute;left:5.00px;top:483.75px" class="cls_004"><span class="cls_004">to provide their own, different implementation of it. An alternative to this arrangement would</span></div>
<div style="position:absolute;left:5.00px;top:501.75px" class="cls_004"><span class="cls_004">be to just add abstract properties for each command, so that the individual implementations</span></div>
<div style="position:absolute;left:5.00px;top:519.75px" class="cls_004"><span class="cls_004">would be completely up to the developers.</span></div>
<div style="position:absolute;left:52.98px;top:543.00px" class="cls_007"><span class="cls_007">public abstract ICommand Save { get; }</span></div>
<div style="position:absolute;left:5.00px;top:563.25px" class="cls_004"><span class="cls_004">While on the subject of commands, you may remember our basic implementation of the</span></div>
<div style="position:absolute;left:5.00px;top:581.25px" class="cls_007"><span class="cls_007">ActionCommand</span><span class="cls_004"> from </span><span class="cls_015">Chapter 1</span><span class="cls_004">, </span><span class="cls_006">A Smarter Way Of Working With WPF</span><span class="cls_004">. At this point, it is</span></div>
<div style="position:absolute;left:5.00px;top:600.00px" class="cls_004"><span class="cls_004">worth taking a short detour to investigate this further. Note that while the basic</span></div>
<div style="position:absolute;left:5.00px;top:618.00px" class="cls_004"><span class="cls_004">implementation shown works well for most of the time, it can catch us out occasionally and</span></div>
<div style="position:absolute;left:5.00px;top:636.00px" class="cls_004"><span class="cls_004">we may notice that a button hasn't become enabled when it should have.</span></div>
<div style="position:absolute;left:5.00px;top:654.00px" class="cls_004"><span class="cls_004">Let's look at an example of this. Imagine that we have a button in our UI that opens a folder</span></div>
<div style="position:absolute;left:5.00px;top:672.00px" class="cls_004"><span class="cls_004">for the user and is enabled when a certain condition is met in the </span><span class="cls_007">ICommand.CanExecute</span></div>
<div style="position:absolute;left:5.00px;top:690.00px" class="cls_004"><span class="cls_004">method. Let's say that this condition is that the folder should have some content. After all,</span></div>
<div style="position:absolute;left:5.00px;top:708.00px" class="cls_004"><span class="cls_004">there's no point in opening an empty folder for the user.</span></div>
<div style="position:absolute;left:5.00px;top:726.00px" class="cls_004"><span class="cls_004">Now let's imagine that this folder will be filled when the user performs some other operation</span></div>
<div style="position:absolute;left:5.00px;top:744.00px" class="cls_004"><span class="cls_004">in the UI. The user clicks the button that starts this folder-filling function and the application</span></div>
<div style="position:absolute;left:5.00px;top:762.00px" class="cls_004"><span class="cls_004">begins to fill it. At the point that the filling function is complete and the folder now holds</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:76190px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background097.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">some content, the open folder button should become enabled, as its associated command's</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_007"><span class="cls_007">CanExecute</span><span class="cls_004"> condition is now </span><span class="cls_007">true</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">Nevertheless, the </span><span class="cls_007">CanExecute</span><span class="cls_004"> method won't be called at that point and why should it? The</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">button and indeed, the </span><span class="cls_007">CommandManager</span><span class="cls_004"> class has no idea that this background process was</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">occurring and that the condition of the </span><span class="cls_007">CanExecute</span><span class="cls_004"> method has now been met. Luckily, we</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">have a couple of options to address this situation.</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">One option is to raise the </span><span class="cls_007">CanExecuteChanged</span><span class="cls_004"> event manually to make the data bound</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">command sources recheck the output of the </span><span class="cls_007">CanExecute</span><span class="cls_004"> method and update their enabled</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">state accordingly. To do this, we could add another method into our </span><span class="cls_007">ActionCommand</span><span class="cls_004"> class,</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">but we would have to rearrange a few things first.</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">The current implementation doesn't store any references to the event handlers that get</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">attached to the </span><span class="cls_007">CanExecuteChanged</span><span class="cls_004"> event. They're actually being stored in the</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_007"><span class="cls_007">CommandManager</span><span class="cls_004"> class, as they're just passed straight through for the </span><span class="cls_007">RequerySuggested</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">event to handle. In order to be able to raise the event manually, we'll need to store our own</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">references to the handlers and to do that, we'll need an </span><span class="cls_007">EventHandler</span><span class="cls_004"> object.</span></div>
<div style="position:absolute;left:52.98px;top:279.00px" class="cls_007"><span class="cls_007">private EventHandler eventHandler;</span></div>
<div style="position:absolute;left:5.00px;top:299.25px" class="cls_004"><span class="cls_004">Next, we'll need to add the references to the handlers that get attached and remove those</span></div>
<div style="position:absolute;left:5.00px;top:317.25px" class="cls_004"><span class="cls_004">that get detached, while still passing references of them through to the </span><span class="cls_007">RequerySuggested</span></div>
<div style="position:absolute;left:5.00px;top:335.25px" class="cls_004"><span class="cls_004">event of the </span><span class="cls_007">CommandManager</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:52.98px;top:358.50px" class="cls_007"><span class="cls_007">public event EventHandler CanExecuteChanged</span></div>
<div style="position:absolute;left:52.98px;top:372.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:385.50px" class="cls_007"><span class="cls_007">add</span></div>
<div style="position:absolute;left:67.97px;top:399.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:412.50px" class="cls_007"><span class="cls_007">eventHandler += value;</span></div>
<div style="position:absolute;left:82.97px;top:426.00px" class="cls_007"><span class="cls_007">CommandManager.RequerySuggested += value;</span></div>
<div style="position:absolute;left:67.97px;top:439.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:453.00px" class="cls_007"><span class="cls_007">remove</span></div>
<div style="position:absolute;left:67.97px;top:466.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:480.00px" class="cls_007"><span class="cls_007">eventHandler -= value;</span></div>
<div style="position:absolute;left:82.97px;top:493.50px" class="cls_007"><span class="cls_007">CommandManager.RequerySuggested -= value;</span></div>
<div style="position:absolute;left:67.97px;top:507.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:520.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:540.75px" class="cls_004"><span class="cls_004">The final change to our </span><span class="cls_007">ActionCommand</span><span class="cls_004"> class is to add the method that we can call to raise</span></div>
<div style="position:absolute;left:5.00px;top:558.75px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">CanExecuteChanged</span><span class="cls_004"> event when we want the command sources of the UI controls to</span></div>
<div style="position:absolute;left:5.00px;top:576.75px" class="cls_004"><span class="cls_004">retrieve the new </span><span class="cls_007">CanExecute</span><span class="cls_004"> value and update their enabled states.</span></div>
<div style="position:absolute;left:52.98px;top:600.00px" class="cls_007"><span class="cls_007">public void RaiseCanExecuteChanged()</span></div>
<div style="position:absolute;left:52.98px;top:613.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:627.00px" class="cls_007"><span class="cls_007">eventHandler?.Invoke(this, new EventArgs());</span></div>
<div style="position:absolute;left:52.98px;top:640.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:660.75px" class="cls_004"><span class="cls_004">We are now able to raise the </span><span class="cls_007">CanExecuteChanged</span><span class="cls_004"> event whenever we need to, although</span></div>
<div style="position:absolute;left:5.00px;top:678.75px" class="cls_004"><span class="cls_004">we'll also need to change our use of the </span><span class="cls_007">ActionCommand</span><span class="cls_004"> class to do so. Whereas previously,</span></div>
<div style="position:absolute;left:5.00px;top:696.75px" class="cls_004"><span class="cls_004">we were simply returning a new instance each time its getter was called, we'll now need to</span></div>
<div style="position:absolute;left:5.00px;top:714.75px" class="cls_004"><span class="cls_004">keep a reference to each command that we want to have this ability.</span></div>
<div style="position:absolute;left:52.98px;top:738.00px" class="cls_007"><span class="cls_007">private ActionCommand saveCommand = null;</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:76992px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background098.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:16.50px" class="cls_007"><span class="cls_007">public ICommand SaveCommand</span></div>
<div style="position:absolute;left:52.98px;top:30.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:43.50px" class="cls_007"><span class="cls_007">get { return saveCommand ?? (saveCommand =</span></div>
<div style="position:absolute;left:82.97px;top:57.00px" class="cls_007"><span class="cls_007">new ActionCommand(action => Save(), canExecute => CanSave()));</span></div>
<div style="position:absolute;left:52.98px;top:70.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:84.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:104.25px" class="cls_004"><span class="cls_004">If you are unfamiliar with the </span><span class="cls_007">??</span><span class="cls_004"> operator shown in the preceding code, it is known as the</span></div>
<div style="position:absolute;left:5.00px;top:122.25px" class="cls_004"><span class="cls_004">null-coalescing operator and it simply returns the left-hand operand if it is not </span><span class="cls_007">null</span><span class="cls_004">, or the</span></div>
<div style="position:absolute;left:5.00px;top:140.25px" class="cls_004"><span class="cls_004">right-hand operand if it is. In this case, the right-hand operand will initialize the command</span></div>
<div style="position:absolute;left:5.00px;top:158.25px" class="cls_004"><span class="cls_004">and set it to the </span><span class="cls_007">saveCommand</span><span class="cls_004"> variable. Then, to raise the event, we call the new</span></div>
<div style="position:absolute;left:5.00px;top:176.25px" class="cls_007"><span class="cls_007">RaiseCanExecuteChanged</span><span class="cls_004"> method on our </span><span class="cls_007">ActionCommand</span><span class="cls_004"> instance when we have completed</span></div>
<div style="position:absolute;left:5.00px;top:194.25px" class="cls_004"><span class="cls_004">our operation.</span></div>
<div style="position:absolute;left:52.98px;top:217.50px" class="cls_007"><span class="cls_007">private void ExecuteSomeCommand()</span></div>
<div style="position:absolute;left:52.98px;top:231.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:244.50px" class="cls_007"><span class="cls_007">// Perform some operation that fulfils the canExecute condition</span></div>
<div style="position:absolute;left:67.97px;top:258.00px" class="cls_007"><span class="cls_007">// then raise the CanExecuteChanged event of the ActionCommand</span></div>
<div style="position:absolute;left:67.97px;top:271.50px" class="cls_007"><span class="cls_007">saveCommand.RaiseCanExecuteChanged();</span></div>
<div style="position:absolute;left:52.98px;top:285.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:305.25px" class="cls_004"><span class="cls_004">While our method is built into the </span><span class="cls_007">ActionCommand</span><span class="cls_004"> class, at times we may not have access to</span></div>
<div style="position:absolute;left:5.00px;top:323.25px" class="cls_004"><span class="cls_004">the particular instance that we need to raise the event on. It should therefore be noted at</span></div>
<div style="position:absolute;left:5.00px;top:341.25px" class="cls_004"><span class="cls_004">this point that there is another, more direct way that we can get the </span><span class="cls_007">CommandManager</span><span class="cls_004"> class</span></div>
<div style="position:absolute;left:5.00px;top:359.25px" class="cls_004"><span class="cls_004">to raise its </span><span class="cls_007">RequerySuggested</span><span class="cls_004"> event.</span></div>
<div style="position:absolute;left:5.00px;top:377.25px" class="cls_004"><span class="cls_004">In these cases, we can simply call the </span><span class="cls_007">CommandManager.InvalidateRequerySuggested</span></div>
<div style="position:absolute;left:5.00px;top:395.25px" class="cls_004"><span class="cls_004">method. We should also be aware that these methods of raising the </span><span class="cls_007">RequerySuggested</span></div>
<div style="position:absolute;left:5.00px;top:413.25px" class="cls_004"><span class="cls_004">event will only work on the UI thread, so care should be taken when using them with</span></div>
<div style="position:absolute;left:5.00px;top:431.25px" class="cls_004"><span class="cls_004">asynchronous code. Now that our short command-related detour is complete, let's return to</span></div>
<div style="position:absolute;left:5.00px;top:449.25px" class="cls_004"><span class="cls_004">take a look at what other common functionality we might want to put into our View Model</span></div>
<div style="position:absolute;left:5.00px;top:467.25px" class="cls_004"><span class="cls_004">base class.</span></div>
<div style="position:absolute;left:5.00px;top:485.25px" class="cls_004"><span class="cls_004">If we have chosen to use generic base classes for our Data Models then we can take</span></div>
<div style="position:absolute;left:5.00px;top:503.25px" class="cls_004"><span class="cls_004">advantage of that in our </span><span class="cls_007">BaseViewModel</span><span class="cls_004"> class. We can provide generic methods that utilize</span></div>
<div style="position:absolute;left:5.00px;top:521.25px" class="cls_004"><span class="cls_004">members from these generic base classes. Let's take a look at some simple examples.</span></div>
<div style="position:absolute;left:52.98px;top:544.50px" class="cls_007"><span class="cls_007">public T AddNewDataTypeToCollection<S, T>(S collection)</span></div>
<div style="position:absolute;left:67.97px;top:558.00px" class="cls_007"><span class="cls_007">where S : BaseSynchronizableCollection<T></span></div>
<div style="position:absolute;left:67.97px;top:571.50px" class="cls_007"><span class="cls_007">where T : BaseSynchronizableDataModel<T>, new()</span></div>
<div style="position:absolute;left:52.98px;top:585.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:598.50px" class="cls_007"><span class="cls_007">T item = collection.GetNewItem();</span></div>
<div style="position:absolute;left:67.97px;top:612.00px" class="cls_007"><span class="cls_007">if (item is IAuditable)</span></div>
<div style="position:absolute;left:82.97px;top:625.50px" class="cls_007"><span class="cls_007">((IAuditable)item).Auditable.CreatedOn = DateTime.Now;</span></div>
<div style="position:absolute;left:67.97px;top:639.00px" class="cls_007"><span class="cls_007">item.Synchronize();</span></div>
<div style="position:absolute;left:67.97px;top:652.50px" class="cls_007"><span class="cls_007">collection.Add(item);</span></div>
<div style="position:absolute;left:67.97px;top:666.00px" class="cls_007"><span class="cls_007">collection.CurrentItem = item;</span></div>
<div style="position:absolute;left:67.97px;top:679.50px" class="cls_007"><span class="cls_007">return item;</span></div>
<div style="position:absolute;left:52.98px;top:693.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:720.00px" class="cls_007"><span class="cls_007">public T InsertNewDataTypeToCollection<S, T>(int index, S</span></div>
<div style="position:absolute;left:52.98px;top:733.50px" class="cls_007"><span class="cls_007">collection)</span></div>
<div style="position:absolute;left:67.97px;top:747.00px" class="cls_007"><span class="cls_007">where S : BaseSynchronizableCollection<T></span></div>
<div style="position:absolute;left:67.97px;top:760.50px" class="cls_007"><span class="cls_007">where T : BaseSynchronizableDataModel<T>, new()</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:77794px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background099.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:3.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:16.50px" class="cls_007"><span class="cls_007">T item = collection.GetNewItem();</span></div>
<div style="position:absolute;left:67.97px;top:30.00px" class="cls_007"><span class="cls_007">if (item is IAuditable)</span></div>
<div style="position:absolute;left:82.97px;top:43.50px" class="cls_007"><span class="cls_007">((IAuditable)item).Auditable.CreatedOn = DateTime.Now;</span></div>
<div style="position:absolute;left:67.97px;top:57.00px" class="cls_007"><span class="cls_007">item.Synchronize();</span></div>
<div style="position:absolute;left:67.97px;top:70.50px" class="cls_007"><span class="cls_007">collection.Insert(index, item);</span></div>
<div style="position:absolute;left:67.97px;top:84.00px" class="cls_007"><span class="cls_007">collection.CurrentItem = item;</span></div>
<div style="position:absolute;left:67.97px;top:97.50px" class="cls_007"><span class="cls_007">return item;</span></div>
<div style="position:absolute;left:52.98px;top:111.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:138.00px" class="cls_007"><span class="cls_007">public void RemoveDataTypeFromCollection<S, T>(S collection, T</span></div>
<div style="position:absolute;left:52.98px;top:151.50px" class="cls_007"><span class="cls_007">item)</span></div>
<div style="position:absolute;left:67.97px;top:165.00px" class="cls_007"><span class="cls_007">where S : BaseSynchronizableCollection<T></span></div>
<div style="position:absolute;left:67.97px;top:178.50px" class="cls_007"><span class="cls_007">where T : BaseSynchronizableDataModel<T>, new()</span></div>
<div style="position:absolute;left:52.98px;top:192.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:205.50px" class="cls_007"><span class="cls_007">int index = collection.IndexOf(item);</span></div>
<div style="position:absolute;left:67.97px;top:219.00px" class="cls_007"><span class="cls_007">collection.RemoveAt(index);</span></div>
<div style="position:absolute;left:67.97px;top:232.50px" class="cls_007"><span class="cls_007">if (index > collection.Count) index = collection.Count;</span></div>
<div style="position:absolute;left:67.97px;top:246.00px" class="cls_007"><span class="cls_007">else if (index < 0) index++;</span></div>
<div style="position:absolute;left:67.97px;top:259.50px" class="cls_007"><span class="cls_007">if (index > 0 && index < collection.Count &&</span></div>
<div style="position:absolute;left:82.97px;top:273.00px" class="cls_007"><span class="cls_007">collection.CurrentItem != collection[index])</span></div>
<div style="position:absolute;left:82.97px;top:286.50px" class="cls_007"><span class="cls_007">collection.CurrentItem = collection[index];</span></div>
<div style="position:absolute;left:52.98px;top:300.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:320.25px" class="cls_004"><span class="cls_004">Here, we see three simple methods that encapsulate more common functionality. Note that</span></div>
<div style="position:absolute;left:5.00px;top:338.25px" class="cls_004"><span class="cls_004">we must specify the same generic type constraints that are declared on our bass classes.</span></div>
<div style="position:absolute;left:5.00px;top:356.25px" class="cls_004"><span class="cls_004">Failure to do so would either result in compilation errors or us not being able to use our</span></div>
<div style="position:absolute;left:5.00px;top:374.25px" class="cls_004"><span class="cls_004">Data Model classes with these methods.</span></div>
<div style="position:absolute;left:5.00px;top:392.25px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">AddNewDataTypeToCollection</span><span class="cls_004"> and </span><span class="cls_007">InsertNewDataTypeToCollection</span><span class="cls_004"> methods are</span></div>
<div style="position:absolute;left:5.00px;top:410.25px" class="cls_004"><span class="cls_004">almost identical and start by creating a new item of the relevant type using the </span><span class="cls_007">GetNewItem</span></div>
<div style="position:absolute;left:5.00px;top:428.25px" class="cls_004"><span class="cls_004">method of our generic </span><span class="cls_007">BaseSynchronizableCollection</span><span class="cls_004"> class. Next, we see another use for</span></div>
<div style="position:absolute;left:5.00px;top:446.25px" class="cls_004"><span class="cls_004">our </span><span class="cls_007">IAuditable</span><span class="cls_004"> interface. In this case, we set the </span><span class="cls_007">CreatedOn</span><span class="cls_004"> date of the new item if it</span></div>
<div style="position:absolute;left:5.00px;top:464.25px" class="cls_004"><span class="cls_004">implements this interface.</span></div>
<div style="position:absolute;left:5.00px;top:482.25px" class="cls_004"><span class="cls_004">Because we declared the generic type constraint on the </span><span class="cls_007">T</span><span class="cls_004"> type parameter that specifies</span></div>
<div style="position:absolute;left:5.00px;top:500.25px" class="cls_004"><span class="cls_004">that it must be, or extend, the </span><span class="cls_007">BaseSynchronizableDataModel</span><span class="cls_004"> class, we are able to call the</span></div>
<div style="position:absolute;left:5.00px;top:518.25px" class="cls_007"><span class="cls_007">Synchronize</span><span class="cls_004"> method to synchronize the new item. We then add the item to the collection</span></div>
<div style="position:absolute;left:5.00px;top:536.25px" class="cls_004"><span class="cls_004">and set it as the value of the </span><span class="cls_007">CurrentItem</span><span class="cls_004"> property. Finally, both methods return the new</span></div>
<div style="position:absolute;left:5.00px;top:554.25px" class="cls_004"><span class="cls_004">item.</span></div>
<div style="position:absolute;left:5.00px;top:572.25px" class="cls_004"><span class="cls_004">The last method performs the opposite action; it removes an item from the collection.</span></div>
<div style="position:absolute;left:5.00px;top:590.25px" class="cls_004"><span class="cls_004">Before doing so, it checks the item's position in the collection and sets the </span><span class="cls_007">CurrentItem</span></div>
<div style="position:absolute;left:5.00px;top:608.25px" class="cls_004"><span class="cls_004">property to the next item if possible, or the next nearest item if the removed item was the</span></div>
<div style="position:absolute;left:5.00px;top:626.25px" class="cls_004"><span class="cls_004">last item in the collection.</span></div>
<div style="position:absolute;left:5.00px;top:644.25px" class="cls_004"><span class="cls_004">Once again, we see how we can encapsulate commonly used functionality into our base</span></div>
<div style="position:absolute;left:5.00px;top:662.25px" class="cls_004"><span class="cls_004">class and save the users of our framework both time and effort re-implementing this</span></div>
<div style="position:absolute;left:5.00px;top:680.25px" class="cls_004"><span class="cls_004">functionality in each View Model class themselves. We can package up any common</span></div>
<div style="position:absolute;left:5.00px;top:698.25px" class="cls_004"><span class="cls_004">functionality that we require in this manner. Having now seen several examples of providing</span></div>
<div style="position:absolute;left:5.00px;top:716.25px" class="cls_004"><span class="cls_004">functionality in our base classes, let's now turn our attention to providing separation</span></div>
<div style="position:absolute;left:5.00px;top:734.25px" class="cls_004"><span class="cls_004">between the components of our framework.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:78596px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background100.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_008"><span class="cls_008">Separating the Data Access Layer</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">Now that we've had a look at providing a variety of functionality through our base classes</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">and interfaces, let's investigate how we can provide the Separation of Concerns that is</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">crucial when using the MVVM pattern. Once again, we turn to the humble interface to help</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">us to achieve this. Let's view a simplified example:</span></div>
<div style="position:absolute;left:52.98px;top:117.00px" class="cls_007"><span class="cls_007">using System;</span></div>
<div style="position:absolute;left:52.98px;top:130.50px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.DataModels;</span></div>
<div style="position:absolute;left:52.98px;top:157.50px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.Models.Interfaces</span></div>
<div style="position:absolute;left:52.98px;top:171.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:184.50px" class="cls_007"><span class="cls_007">public interface IDataProvider</span></div>
<div style="position:absolute;left:67.97px;top:198.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:211.50px" class="cls_007"><span class="cls_007">User GetUser(Guid id);</span></div>
<div style="position:absolute;left:82.97px;top:238.50px" class="cls_007"><span class="cls_007">bool SaveUser(User user);</span></div>
<div style="position:absolute;left:67.97px;top:252.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:265.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:285.75px" class="cls_004"><span class="cls_004">We start off with a very simple interface. Of course, real applications will have a great</span></div>
<div style="position:absolute;left:5.00px;top:303.75px" class="cls_004"><span class="cls_004">many more methods than this, but the principal is the same, regardless of the complexity of</span></div>
<div style="position:absolute;left:5.00px;top:321.75px" class="cls_004"><span class="cls_004">the interface. So here, we just have a </span><span class="cls_007">GetUser</span><span class="cls_004"> and a </span><span class="cls_007">SaveUser</span><span class="cls_004"> method that our</span></div>
<div style="position:absolute;left:5.00px;top:339.75px" class="cls_007"><span class="cls_007">DataProvider</span><span class="cls_004"> classes need to implement. Now let's look at the </span><span class="cls_007">ApplicationDataProvider</span></div>
<div style="position:absolute;left:5.00px;top:357.75px" class="cls_004"><span class="cls_004">class:</span></div>
<div style="position:absolute;left:52.98px;top:381.00px" class="cls_007"><span class="cls_007">using System;</span></div>
<div style="position:absolute;left:52.98px;top:394.50px" class="cls_007"><span class="cls_007">using System.Data.Linq;</span></div>
<div style="position:absolute;left:52.98px;top:408.00px" class="cls_007"><span class="cls_007">using System.Linq;</span></div>
<div style="position:absolute;left:52.98px;top:421.50px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.DataModels;</span></div>
<div style="position:absolute;left:52.98px;top:435.00px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.Models.Interfaces;</span></div>
<div style="position:absolute;left:52.98px;top:462.00px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.Models.DataProviders</span></div>
<div style="position:absolute;left:52.98px;top:475.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:489.00px" class="cls_007"><span class="cls_007">public class ApplicationDataProvider : IDataProvider</span></div>
<div style="position:absolute;left:67.97px;top:502.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:516.00px" class="cls_007"><span class="cls_007">public ApplicationDataContext DataContext</span></div>
<div style="position:absolute;left:82.97px;top:529.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:543.00px" class="cls_007"><span class="cls_007">get { return new ApplicationDataContext(); }</span></div>
<div style="position:absolute;left:82.97px;top:556.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:583.50px" class="cls_007"><span class="cls_007">public User GetUser(Guid id)</span></div>
<div style="position:absolute;left:82.97px;top:597.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:610.50px" class="cls_007"><span class="cls_007">DbUser dbUser = DataContext.DbUsers.SingleOrDefault(u => u.Id</span></div>
<div style="position:absolute;left:52.98px;top:624.00px" class="cls_007"><span class="cls_007">==</span></div>
<div style="position:absolute;left:75.47px;top:624.00px" class="cls_007"><span class="cls_007">id);</span></div>
<div style="position:absolute;left:97.96px;top:637.50px" class="cls_007"><span class="cls_007">if (dbUser == null) return null;</span></div>
<div style="position:absolute;left:97.96px;top:651.00px" class="cls_007"><span class="cls_007">return new User(dbUser.Id, dbUser.Name, dbUser.Age);</span></div>
<div style="position:absolute;left:82.97px;top:664.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:691.50px" class="cls_007"><span class="cls_007">public bool SaveUser(User user)</span></div>
<div style="position:absolute;left:82.97px;top:705.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:718.50px" class="cls_007"><span class="cls_007">using (ApplicationDataContext dataContext = DataContext)</span></div>
<div style="position:absolute;left:97.96px;top:732.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:112.96px;top:745.50px" class="cls_007"><span class="cls_007">DbUser dbUser =</span></div>
<div style="position:absolute;left:127.95px;top:759.00px" class="cls_007"><span class="cls_007">dataContext.DbUsers.SingleOrDefault(u => u.Id ==</span></div>
<div style="position:absolute;left:52.98px;top:772.50px" class="cls_007"><span class="cls_007">user.Id);</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:79398px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background101.jpg" width=612 height=792></div>
<div style="position:absolute;left:112.96px;top:3.00px" class="cls_007"><span class="cls_007">if (dbUser == null) return false;</span></div>
<div style="position:absolute;left:112.96px;top:16.50px" class="cls_007"><span class="cls_007">dbUser.Name = user.Name;</span></div>
<div style="position:absolute;left:112.96px;top:30.00px" class="cls_007"><span class="cls_007">dbUser.Age = user.Age;</span></div>
<div style="position:absolute;left:52.98px;top:57.00px" class="cls_007"><span class="cls_007">dataContext.SubmitChanges(ConflictMode.FailOnFirstConflict);</span></div>
<div style="position:absolute;left:112.96px;top:70.50px" class="cls_007"><span class="cls_007">return true;</span></div>
<div style="position:absolute;left:97.96px;top:84.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:97.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:111.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:124.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:144.75px" class="cls_004"><span class="cls_004">This </span><span class="cls_007">ApplicationDataProvider</span><span class="cls_004"> class uses some simple LINQ to SQL to query and update</span></div>
<div style="position:absolute;left:5.00px;top:162.75px" class="cls_004"><span class="cls_004">a database for the </span><span class="cls_007">User</span><span class="cls_004"> specified by the provided </span><span class="cls_007">id</span><span class="cls_004"> value. That means that this particular</span></div>
<div style="position:absolute;left:5.00px;top:180.75px" class="cls_004"><span class="cls_004">implementation of the interface requires a connection to a database. We want to avoid</span></div>
<div style="position:absolute;left:5.00px;top:198.75px" class="cls_004"><span class="cls_004">having this dependency when testing our application, so we'll need another implementation</span></div>
<div style="position:absolute;left:5.00px;top:216.75px" class="cls_004"><span class="cls_004">of the interface to use for testing purposes. Let's take a look at our mock implementation</span></div>
<div style="position:absolute;left:5.00px;top:234.75px" class="cls_004"><span class="cls_004">now.</span></div>
<div style="position:absolute;left:52.98px;top:258.00px" class="cls_007"><span class="cls_007">using System;</span></div>
<div style="position:absolute;left:52.98px;top:271.50px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.DataModels;</span></div>
<div style="position:absolute;left:52.98px;top:285.00px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.Models.Interfaces;</span></div>
<div style="position:absolute;left:52.98px;top:312.00px" class="cls_007"><span class="cls_007">namespace Test.CompanyName.ApplicationName.Models.DataProviders</span></div>
<div style="position:absolute;left:52.98px;top:325.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:339.00px" class="cls_007"><span class="cls_007">public class MockDataProvider : IDataProvider</span></div>
<div style="position:absolute;left:67.97px;top:352.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:366.00px" class="cls_007"><span class="cls_007">public User GetUser(Guid id)</span></div>
<div style="position:absolute;left:82.97px;top:379.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:393.00px" class="cls_007"><span class="cls_007">return new User(id, "John Smith", 25);</span></div>
<div style="position:absolute;left:82.97px;top:406.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:433.50px" class="cls_007"><span class="cls_007">public bool SaveUser(User user)</span></div>
<div style="position:absolute;left:82.97px;top:447.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:460.50px" class="cls_007"><span class="cls_007">return true;</span></div>
<div style="position:absolute;left:82.97px;top:474.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:487.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:501.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:521.25px" class="cls_004"><span class="cls_004">In this </span><span class="cls_007">MockDataProvider</span><span class="cls_004"> implementation of the </span><span class="cls_007">IDataProvider</span><span class="cls_004"> interface, we can see that</span></div>
<div style="position:absolute;left:5.00px;top:539.25px" class="cls_004"><span class="cls_004">the data is just manually mocked. In fact, it just returns the one single </span><span class="cls_007">User</span><span class="cls_004"> from the</span></div>
<div style="position:absolute;left:5.00px;top:557.25px" class="cls_007"><span class="cls_007">GetUser</span><span class="cls_004"> method and always returns </span><span class="cls_007">true</span><span class="cls_004"> from the </span><span class="cls_007">SaveUser</span><span class="cls_004"> method, so it's fairly useless.</span></div>
<div style="position:absolute;left:5.00px;top:575.25px" class="cls_004"><span class="cls_004">In a real-world application, we would either utilize a mocking framework, or manually mock</span></div>
<div style="position:absolute;left:5.00px;top:593.25px" class="cls_004"><span class="cls_004">up some more substantial testing data. Still, this will suffice for the point that we are</span></div>
<div style="position:absolute;left:5.00px;top:611.25px" class="cls_004"><span class="cls_004">focusing on here. Now that we've seen the classes involved, let's look at how they might be</span></div>
<div style="position:absolute;left:5.00px;top:629.25px" class="cls_004"><span class="cls_004">used.</span></div>
<div style="position:absolute;left:5.00px;top:647.25px" class="cls_004"><span class="cls_004">The idea is that we have some sort of </span><span class="cls_007">DataController</span><span class="cls_004"> class or classes that sit between the</span></div>
<div style="position:absolute;left:5.00px;top:665.25px" class="cls_007"><span class="cls_007">IDataProvider</span><span class="cls_004"> interface and the View Model classes. The View Model classes request</span></div>
<div style="position:absolute;left:5.00px;top:683.25px" class="cls_004"><span class="cls_004">data from the </span><span class="cls_007">DataController</span><span class="cls_004"> class and in turn, it requests data through the interface. It</span></div>
<div style="position:absolute;left:5.00px;top:701.25px" class="cls_004"><span class="cls_004">therefore mirrors the methods of the interface and typically introduces some extra</span></div>
<div style="position:absolute;left:5.00px;top:719.25px" class="cls_004"><span class="cls_004">functionality, such as feedback handling for example. Let's see what our simplified</span></div>
<div style="position:absolute;left:5.00px;top:737.25px" class="cls_007"><span class="cls_007">DataController</span><span class="cls_004"> class looks like:</span></div>
<div style="position:absolute;left:52.98px;top:760.50px" class="cls_007"><span class="cls_007">using System;</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:80200px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background102.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:3.00px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.DataModels;</span></div>
<div style="position:absolute;left:52.98px;top:16.50px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.Models.Interfaces;</span></div>
<div style="position:absolute;left:52.98px;top:43.50px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.Models.DataControllers</span></div>
<div style="position:absolute;left:52.98px;top:57.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:70.50px" class="cls_007"><span class="cls_007">public class DataController</span></div>
<div style="position:absolute;left:67.97px;top:84.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:97.50px" class="cls_007"><span class="cls_007">private IDataProvider dataProvider;</span></div>
<div style="position:absolute;left:82.97px;top:124.50px" class="cls_007"><span class="cls_007">public DataController(IDataProvider dataProvider)</span></div>
<div style="position:absolute;left:82.97px;top:138.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:151.50px" class="cls_007"><span class="cls_007">DataProvider = dataProvider;</span></div>
<div style="position:absolute;left:82.97px;top:165.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:192.00px" class="cls_007"><span class="cls_007">protected IDataProvider DataProvider</span></div>
<div style="position:absolute;left:82.97px;top:205.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:219.00px" class="cls_007"><span class="cls_007">get { return dataProvider; }</span></div>
<div style="position:absolute;left:97.96px;top:232.50px" class="cls_007"><span class="cls_007">private set { dataProvider = value; }</span></div>
<div style="position:absolute;left:82.97px;top:246.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:273.00px" class="cls_007"><span class="cls_007">public User GetUser(Guid id)</span></div>
<div style="position:absolute;left:82.97px;top:286.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:300.00px" class="cls_007"><span class="cls_007">return DataProvider.GetUser(id);</span></div>
<div style="position:absolute;left:82.97px;top:313.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:340.50px" class="cls_007"><span class="cls_007">public bool SaveUser(User user)</span></div>
<div style="position:absolute;left:82.97px;top:354.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:367.50px" class="cls_007"><span class="cls_007">return DataProvider.SaveUser(user);</span></div>
<div style="position:absolute;left:82.97px;top:381.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:394.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:408.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:428.25px" class="cls_004"><span class="cls_004">As we can see, the </span><span class="cls_007">DataController</span><span class="cls_004"> class has a private member variable of type</span></div>
<div style="position:absolute;left:5.00px;top:446.25px" class="cls_007"><span class="cls_007">IDataProvider</span><span class="cls_004">, which is populated in its constructor. It is this variable that is used to</span></div>
<div style="position:absolute;left:5.00px;top:464.25px" class="cls_004"><span class="cls_004">access the application data source. When the application is running, an instance of our</span></div>
<div style="position:absolute;left:5.00px;top:482.25px" class="cls_007"><span class="cls_007">ApplicationDataProvider</span><span class="cls_004"> class is used to instantiate the </span><span class="cls_007">DataController</span><span class="cls_004"> class and so our</span></div>
<div style="position:absolute;left:5.00px;top:500.25px" class="cls_004"><span class="cls_004">actual data source is used.</span></div>
<div style="position:absolute;left:52.98px;top:523.50px" class="cls_007"><span class="cls_007">DataController dataController =</span></div>
<div style="position:absolute;left:67.97px;top:537.00px" class="cls_007"><span class="cls_007">new DataController(new ApplicationDataProvider());</span></div>
<div style="position:absolute;left:5.00px;top:557.25px" class="cls_004"><span class="cls_004">However, when we are testing our application, we can use an instance of our</span></div>
<div style="position:absolute;left:5.00px;top:575.25px" class="cls_007"><span class="cls_007">MockDataProvider</span><span class="cls_004"> class to instantiate the </span><span class="cls_007">DataController</span><span class="cls_004"> class instead, thereby eliminating</span></div>
<div style="position:absolute;left:5.00px;top:593.25px" class="cls_004"><span class="cls_004">our dependency to the actual data source.</span></div>
<div style="position:absolute;left:52.98px;top:616.50px" class="cls_007"><span class="cls_007">DataController dataController = new DataController(new</span></div>
<div style="position:absolute;left:52.98px;top:630.00px" class="cls_007"><span class="cls_007">MockDataProvider());</span></div>
<div style="position:absolute;left:5.00px;top:650.25px" class="cls_004"><span class="cls_004">In this way, we can swap out the code that provides the data for the View Models, while</span></div>
<div style="position:absolute;left:5.00px;top:668.25px" class="cls_004"><span class="cls_004">keeping the rest of the code unchanged. This enables us to test the code in the View</span></div>
<div style="position:absolute;left:5.00px;top:686.25px" class="cls_004"><span class="cls_004">Models without having to be connected to our actual data storage device. In the next</span></div>
<div style="position:absolute;left:5.00px;top:704.25px" class="cls_004"><span class="cls_004">section, we'll see better ways to initialize these classes, but for now, let's see what else our</span></div>
<div style="position:absolute;left:5.00px;top:722.25px" class="cls_007"><span class="cls_007">DataController</span><span class="cls_004"> class could do for us.</span></div>
<div style="position:absolute;left:5.00px;top:740.25px" class="cls_004"><span class="cls_004">Interfaces become more useful when they are used by parts of the application framework,</span></div>
<div style="position:absolute;left:5.00px;top:758.25px" class="cls_004"><span class="cls_004">other than the implementing classes. Apart from than defining some auditing properties and</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:81002px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background103.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">having the possibility of outputting their values, our earlier </span><span class="cls_007">IAuditable</span><span class="cls_004"> interface example is</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">not overly useful. We could however, extend its functionality further in our </span><span class="cls_007">DataController</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">class, by automatically updating its values. We'll need to add some more members to</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">achieve this:</span></div>
<div style="position:absolute;left:52.98px;top:81.00px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.DataModels.Interfaces;</span></div>
<div style="position:absolute;left:52.98px;top:135.00px" class="cls_007"><span class="cls_007">public User CurrentUser { get; set; }</span></div>
<div style="position:absolute;left:52.98px;top:189.00px" class="cls_007"><span class="cls_007">private void SetAuditUpdateFields<T>(T dataModel) where T :</span></div>
<div style="position:absolute;left:52.98px;top:202.50px" class="cls_007"><span class="cls_007">IAuditable</span></div>
<div style="position:absolute;left:52.98px;top:216.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:229.50px" class="cls_007"><span class="cls_007">dataModel.Auditable.UpdatedOn = DateTime.Now;</span></div>
<div style="position:absolute;left:67.97px;top:243.00px" class="cls_007"><span class="cls_007">dataModel.Auditable.UpdatedBy = CurrentUser;</span></div>
<div style="position:absolute;left:67.97px;top:256.50px" class="cls_007"><span class="cls_007">return dataModel;</span></div>
<div style="position:absolute;left:52.98px;top:270.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:290.25px" class="cls_004"><span class="cls_004">We first need to add a property of type </span><span class="cls_007">User</span><span class="cls_004"> that we will use to set the value of the current</span></div>
<div style="position:absolute;left:5.00px;top:308.25px" class="cls_004"><span class="cls_004">user of the application. This can be set as new users login to the application. Next, we need</span></div>
<div style="position:absolute;left:5.00px;top:326.25px" class="cls_004"><span class="cls_004">a method to update the "updated" values of our </span><span class="cls_007">IAuditable</span><span class="cls_004"> interface. Again, we add a</span></div>
<div style="position:absolute;left:5.00px;top:344.25px" class="cls_004"><span class="cls_004">generic type constraint to ensure that only objects that implement our interface can be</span></div>
<div style="position:absolute;left:5.00px;top:362.25px" class="cls_004"><span class="cls_004">passed into this method. The result of this is that the developers that use our application</span></div>
<div style="position:absolute;left:5.00px;top:380.25px" class="cls_004"><span class="cls_004">framework can easily update these values.</span></div>
<div style="position:absolute;left:52.98px;top:403.50px" class="cls_007"><span class="cls_007">public bool SaveUser(User user)</span></div>
<div style="position:absolute;left:52.98px;top:417.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:430.50px" class="cls_007"><span class="cls_007">return DataProvider.SaveUser(SetAuditUpdateFields(user));</span></div>
<div style="position:absolute;left:52.98px;top:444.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:464.25px" class="cls_004"><span class="cls_004">We could add a similar method to set the "created" audit properties when adding new</span></div>
<div style="position:absolute;left:5.00px;top:482.25px" class="cls_004"><span class="cls_004">objects.</span></div>
<div style="position:absolute;left:52.98px;top:505.50px" class="cls_007"><span class="cls_007">public bool AddUser(User user)</span></div>
<div style="position:absolute;left:52.98px;top:519.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:532.50px" class="cls_007"><span class="cls_007">return DataProvider.AddUser(SetAuditCreateFields(user));</span></div>
<div style="position:absolute;left:52.98px;top:546.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:600.00px" class="cls_007"><span class="cls_007">private void SetAuditCreateFields<T>(T dataModel) where T :</span></div>
<div style="position:absolute;left:52.98px;top:613.50px" class="cls_007"><span class="cls_007">IAuditable</span></div>
<div style="position:absolute;left:52.98px;top:627.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:640.50px" class="cls_007"><span class="cls_007">dataModel.Auditable.CreatedOn = DateTime.Now;</span></div>
<div style="position:absolute;left:67.97px;top:654.00px" class="cls_007"><span class="cls_007">dataModel.Auditable.CreatedBy = CurrentUser;</span></div>
<div style="position:absolute;left:67.97px;top:667.50px" class="cls_007"><span class="cls_007">return dataModel;</span></div>
<div style="position:absolute;left:52.98px;top:681.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:701.25px" class="cls_004"><span class="cls_004">Continuing this example, we could extend the constructor of our </span><span class="cls_007">DataController</span><span class="cls_004"> class to</span></div>
<div style="position:absolute;left:5.00px;top:719.25px" class="cls_004"><span class="cls_004">accept a </span><span class="cls_007">User</span><span class="cls_004"> input parameter that we can use to set our </span><span class="cls_007">CurrentUser</span><span class="cls_004"> property with:</span></div>
<div style="position:absolute;left:52.98px;top:742.50px" class="cls_007"><span class="cls_007">public DataController(IDataProvider dataProvider, User currentUser)</span></div>
<div style="position:absolute;left:52.98px;top:756.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:769.50px" class="cls_007"><span class="cls_007">DataProvider = dataProvider;</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:81804px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background104.jpg" width=612 height=792></div>
<div style="position:absolute;left:67.97px;top:3.00px" class="cls_007"><span class="cls_007">CurrentUser = currentUser;</span></div>
<div style="position:absolute;left:52.98px;top:16.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:49.50px" class="cls_004"><span class="cls_004">We could then expose our data source to our View Models through their base class using a</span></div>
<div style="position:absolute;left:5.00px;top:67.50px" class="cls_007"><span class="cls_007">CurrentUser</span><span class="cls_004"> property in the </span><span class="cls_007">StateManager</span><span class="cls_004"> class and the </span><span class="cls_007">DependencyManager</span><span class="cls_004"> class that we'll</span></div>
<div style="position:absolute;left:5.00px;top:85.50px" class="cls_004"><span class="cls_004">see in the following sections.</span></div>
<div style="position:absolute;left:52.98px;top:108.75px" class="cls_007"><span class="cls_007">protected DataController Model</span></div>
<div style="position:absolute;left:52.98px;top:122.25px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:135.75px" class="cls_007"><span class="cls_007">get { return new DataController(</span></div>
<div style="position:absolute;left:82.97px;top:149.25px" class="cls_007"><span class="cls_007">DependencyManager.Instance.Resolve<IDataProvider>(),</span></div>
<div style="position:absolute;left:82.97px;top:162.75px" class="cls_007"><span class="cls_007">StateManager.CurrentUser); }</span></div>
<div style="position:absolute;left:52.98px;top:176.25px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:196.50px" class="cls_004"><span class="cls_004">Essentially, anything that we need to do to the data coming from our application data</span></div>
<div style="position:absolute;left:5.00px;top:214.50px" class="cls_004"><span class="cls_004">source can be achieved in a single </span><span class="cls_007">DataController</span><span class="cls_004"> class. However, if we require several</span></div>
<div style="position:absolute;left:5.00px;top:232.50px" class="cls_004"><span class="cls_004">different modifications, then we could alternatively create several controller classes and</span></div>
<div style="position:absolute;left:5.00px;top:250.50px" class="cls_004"><span class="cls_004">chain them together, with each performing their separate tasks in turn. As they could all</span></div>
<div style="position:absolute;left:5.00px;top:268.50px" class="cls_004"><span class="cls_004">implement the same methods, they could all potentially implement the same interface.</span></div>
<div style="position:absolute;left:5.00px;top:456.75px" class="cls_004"><span class="cls_004">We'll see an example of this in </span><span class="cls_015">Chapter 9</span><span class="cls_004">, </span><span class="cls_006">Completing That Great User Experience</span><span class="cls_004">, but</span></div>
<div style="position:absolute;left:5.00px;top:475.50px" class="cls_004"><span class="cls_004">now that we have a good idea on how best to setup our application data source</span></div>
<div style="position:absolute;left:5.00px;top:493.50px" class="cls_004"><span class="cls_004">connections to provide the separation required by the MVVM pattern, we can focus on the</span></div>
<div style="position:absolute;left:5.00px;top:511.50px" class="cls_004"><span class="cls_004">next way of building functionality into our framework. Let's move on to discover how we can</span></div>
<div style="position:absolute;left:5.00px;top:529.50px" class="cls_004"><span class="cls_004">plug more complex and/or specialized functionality into our framework.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:82606px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background105.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_008"><span class="cls_008">Providing services</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">The job of the base classes and interfaces in our application framework are to encapsulate</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">functionality that is commonly used by our View Models and Data Models. When the</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">required functionality is more complex, or when it involves particular resources, or external</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">connections, we implement it in separate service, or manager classes. For the remainder of</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">this book, we will refer to these as manager classes. In larger applications, these are</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">typically provided in a separate project.</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">Encapsulating them in a separate project enables us to reuse the functionality from these</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">classes in our other applications. Which classes we use in this project will depend on the</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">requirements of the application that we're building, but it will often include classes that</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">provide the ability to send e-mails, to access the end user's hard drive, to export data in</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">various formats, or to manage global application state for example.</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">We will investigate a number of these classes in this book, so that we have a good idea of</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">how to implement our own custom manager classes. The most commonly used of these</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">classes can normally be accessed directly from the base View Model class via properties.</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">There are a few different ways that we can expose these classes to the View Models, so</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">let's examine them.</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_004"><span class="cls_004">When a manger class is used often and for short durations each time, we can expose a</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_004"><span class="cls_004">new instance of them each time, like this:</span></div>
<div style="position:absolute;left:52.98px;top:369.00px" class="cls_007"><span class="cls_007">public FeedbackManager FeedbackManager</span></div>
<div style="position:absolute;left:52.98px;top:382.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:396.00px" class="cls_007"><span class="cls_007">get { return new FeedbackManager(); }</span></div>
<div style="position:absolute;left:52.98px;top:409.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:429.75px" class="cls_004"><span class="cls_004">However, if a manager class is required for the life of the application, because it must</span></div>
<div style="position:absolute;left:5.00px;top:447.75px" class="cls_004"><span class="cls_004">remember some state or configuration for example, then we typically use the </span><span class="cls_007">static</span></div>
<div style="position:absolute;left:5.00px;top:465.75px" class="cls_004"><span class="cls_004">keyword in one way or another. The simplest option would be to declare a normal class, but</span></div>
<div style="position:absolute;left:5.00px;top:483.75px" class="cls_004"><span class="cls_004">expose it via a static property.</span></div>
<div style="position:absolute;left:52.98px;top:507.00px" class="cls_007"><span class="cls_007">private static StateManager stateManager = new StateManager();</span></div>
<div style="position:absolute;left:52.98px;top:561.00px" class="cls_007"><span class="cls_007">public static StateManager StateManager</span></div>
<div style="position:absolute;left:52.98px;top:574.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:588.00px" class="cls_007"><span class="cls_007">get { return stateManager; }</span></div>
<div style="position:absolute;left:52.98px;top:601.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:621.75px" class="cls_004"><span class="cls_004">An alternative method of having one and only one instance of a class being instantiated and</span></div>
<div style="position:absolute;left:5.00px;top:639.75px" class="cls_004"><span class="cls_004">having it stay alive for as long as the application is running is for us to use the Singleton</span></div>
<div style="position:absolute;left:5.00px;top:657.75px" class="cls_004"><span class="cls_004">pattern. While it was all the rage twenty or so years ago, it has unfortunately recently fallen</span></div>
<div style="position:absolute;left:5.00px;top:675.75px" class="cls_004"><span class="cls_004">foul of more modern programming principles, such as the likes of SOLID, that states that</span></div>
<div style="position:absolute;left:5.00px;top:693.75px" class="cls_004"><span class="cls_004">each class should have a single responsibility.</span></div>
<div style="position:absolute;left:5.00px;top:711.75px" class="cls_004"><span class="cls_004">The Singleton pattern breaks this principle as it serves whatever purpose we design it for,</span></div>
<div style="position:absolute;left:5.00px;top:729.75px" class="cls_004"><span class="cls_004">but it is also responsible for instantiating itself and maintaining a single access point. Before</span></div>
<div style="position:absolute;left:5.00px;top:747.75px" class="cls_004"><span class="cls_004">discussing the merits and pitfalls of this pattern further, let's take a look at how we might</span></div>
<div style="position:absolute;left:5.00px;top:765.75px" class="cls_004"><span class="cls_004">implement it in our manager class:</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:83408px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background106.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:6.00px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.Managers</span></div>
<div style="position:absolute;left:52.98px;top:19.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:33.00px" class="cls_007"><span class="cls_007">public class StateManager</span></div>
<div style="position:absolute;left:67.97px;top:46.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:60.00px" class="cls_007"><span class="cls_007">private static StateManager instance;</span></div>
<div style="position:absolute;left:82.97px;top:87.00px" class="cls_007"><span class="cls_007">private StateManager() { }</span></div>
<div style="position:absolute;left:82.97px;top:114.00px" class="cls_007"><span class="cls_007">public static StateManager Instance</span></div>
<div style="position:absolute;left:82.97px;top:127.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:141.00px" class="cls_007"><span class="cls_007">get { return instance ?? (instance = new StateManager()); }</span></div>
<div style="position:absolute;left:82.97px;top:154.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:195.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:208.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:228.75px" class="cls_004"><span class="cls_004">Note that it can be implemented in a variety of ways, but this particular way uses lazy</span></div>
<div style="position:absolute;left:5.00px;top:246.75px" class="cls_004"><span class="cls_004">initialization, where the instance is not instantiated until it is first referenced via the </span><span class="cls_007">Instance</span></div>
<div style="position:absolute;left:5.00px;top:264.75px" class="cls_004"><span class="cls_004">property. Using the </span><span class="cls_007">??</span><span class="cls_004"> operator again, the </span><span class="cls_007">Instance</span><span class="cls_004"> property getter can be read as "return</span></div>
<div style="position:absolute;left:5.00px;top:282.75px" class="cls_004"><span class="cls_004">the one and only instantiated instance if it is not null, or if it is, instantiate the one and only</span></div>
<div style="position:absolute;left:5.00px;top:300.75px" class="cls_004"><span class="cls_004">instance and then return it". The significant part of this pattern is that as there is no public</span></div>
<div style="position:absolute;left:5.00px;top:318.75px" class="cls_004"><span class="cls_004">constructor and therefore the class cannot be externally instantiated, this property is the</span></div>
<div style="position:absolute;left:5.00px;top:336.75px" class="cls_004"><span class="cls_004">single way to access the internal object.</span></div>
<div style="position:absolute;left:5.00px;top:354.75px" class="cls_004"><span class="cls_004">However, this is the very part that causes trouble for some developers, as this makes</span></div>
<div style="position:absolute;left:5.00px;top:372.75px" class="cls_004"><span class="cls_004">inheritance impossible with these classes. In our case though, we won't need to extend our</span></div>
<div style="position:absolute;left:5.00px;top:390.75px" class="cls_007"><span class="cls_007">StateManager</span><span class="cls_004"> class, so that it not a concern for us. Others may point to the problem that</span></div>
<div style="position:absolute;left:5.00px;top:408.75px" class="cls_004"><span class="cls_004">exposing this Singleton class as shown in the following code, will tightly couple it to the base</span></div>
<div style="position:absolute;left:5.00px;top:426.75px" class="cls_004"><span class="cls_004">View Model class that it is declared in.</span></div>
<div style="position:absolute;left:52.98px;top:450.00px" class="cls_007"><span class="cls_007">public StateManager StateManager</span></div>
<div style="position:absolute;left:52.98px;top:463.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:477.00px" class="cls_007"><span class="cls_007">get { return StateManager.Instance; }</span></div>
<div style="position:absolute;left:52.98px;top:490.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:510.75px" class="cls_004"><span class="cls_004">While this is true, what harm is that with this class? Its purpose is to maintain the state of</span></div>
<div style="position:absolute;left:5.00px;top:528.75px" class="cls_004"><span class="cls_004">user settings, common or default values, and values for UI display and operation statuses.</span></div>
<div style="position:absolute;left:5.00px;top:546.75px" class="cls_004"><span class="cls_004">It contains no resources and no real reason to avoid using it when running unit tests, so in</span></div>
<div style="position:absolute;left:5.00px;top:564.75px" class="cls_004"><span class="cls_004">this case, the tight coupling is inconsequential. In this regard, the Singleton pattern</span></div>
<div style="position:absolute;left:5.00px;top:582.75px" class="cls_004"><span class="cls_004">continues to be a useful tool in the right situations, but we should certainly be aware of its</span></div>
<div style="position:absolute;left:5.00px;top:600.75px" class="cls_004"><span class="cls_004">pitfalls all the same.</span></div>
<div style="position:absolute;left:5.00px;top:618.75px" class="cls_004"><span class="cls_004">However, if a particular manger class does utilize resources or creates some form of</span></div>
<div style="position:absolute;left:5.00px;top:636.75px" class="cls_004"><span class="cls_004">connection with the outside world, for example, like an </span><span class="cls_007">EmailManager</span><span class="cls_004"> would, then we will</span></div>
<div style="position:absolute;left:5.00px;top:654.75px" class="cls_004"><span class="cls_004">need to create an interface for it to maintain our Separation of Concerns. Remember that</span></div>
<div style="position:absolute;left:5.00px;top:672.75px" class="cls_004"><span class="cls_004">interfaces enable us to disconnect the actual application components and replace them with</span></div>
<div style="position:absolute;left:5.00px;top:690.75px" class="cls_004"><span class="cls_004">mock components while testing. In these cases, we have to expose the functionality in the</span></div>
<div style="position:absolute;left:5.00px;top:708.75px" class="cls_004"><span class="cls_004">base classes slightly differently.</span></div>
<div style="position:absolute;left:52.98px;top:732.00px" class="cls_007"><span class="cls_007">private IEmailManager emailManager;</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:84210px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background107.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:3.00px" class="cls_007"><span class="cls_007">public BaseViewModel(IEmailManager emailManager)</span></div>
<div style="position:absolute;left:52.98px;top:16.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:30.00px" class="cls_007"><span class="cls_007">this.emailManager = emailManager; }</span></div>
<div style="position:absolute;left:52.98px;top:43.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:97.50px" class="cls_007"><span class="cls_007">public IEmailManager EmailManager</span></div>
<div style="position:absolute;left:52.98px;top:111.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:124.50px" class="cls_007"><span class="cls_007">get { return emailManager; }</span></div>
<div style="position:absolute;left:52.98px;top:138.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:158.25px" class="cls_004"><span class="cls_004">The general idea here is for us to have no direct contact with the manager class in hand,</span></div>
<div style="position:absolute;left:5.00px;top:176.25px" class="cls_004"><span class="cls_004">instead accessing its functionality through the interface methods and properties. By doing</span></div>
<div style="position:absolute;left:5.00px;top:194.25px" class="cls_004"><span class="cls_004">this, we are able to decouple the manager class from the View Models that use it and</span></div>
<div style="position:absolute;left:5.00px;top:212.25px" class="cls_004"><span class="cls_004">therefore enable them to be used independently of each other. Note that this is a very</span></div>
<div style="position:absolute;left:5.00px;top:230.25px" class="cls_004"><span class="cls_004">simple example of Dependency Injection.</span></div>
<div style="position:absolute;left:5.00px;top:247.51px" class="cls_011"><span class="cls_011">Implementing Dependency Injection</span></div>
<div style="position:absolute;left:5.00px;top:277.50px" class="cls_004"><span class="cls_004">Dependency Injection is a well-known design pattern that aids in decoupling various</span></div>
<div style="position:absolute;left:5.00px;top:295.50px" class="cls_004"><span class="cls_004">components of an application. If one class uses another class to perform some functionality</span></div>
<div style="position:absolute;left:5.00px;top:313.50px" class="cls_004"><span class="cls_004">internally, then the class that is internally used becomes a dependency of the class that</span></div>
<div style="position:absolute;left:5.00px;top:331.50px" class="cls_004"><span class="cls_004">uses it. It cannot achieve its objectives without it. In some cases, this is not a problem, but</span></div>
<div style="position:absolute;left:5.00px;top:349.50px" class="cls_004"><span class="cls_004">in others, it can represent a huge problem.</span></div>
<div style="position:absolute;left:5.00px;top:367.50px" class="cls_004"><span class="cls_004">For example, let's imagine that we have a </span><span class="cls_007">FeedbackManager</span><span class="cls_004"> class that is responsible for</span></div>
<div style="position:absolute;left:5.00px;top:385.50px" class="cls_004"><span class="cls_004">providing operational feedback to the end users. In that class, we have a</span></div>
<div style="position:absolute;left:5.00px;top:403.50px" class="cls_007"><span class="cls_007">FeedbackCollection</span><span class="cls_004"> class that holds the </span><span class="cls_007">Feedback</span><span class="cls_004"> objects that are current being displayed</span></div>
<div style="position:absolute;left:5.00px;top:421.50px" class="cls_004"><span class="cls_004">to the current user. Here, the </span><span class="cls_007">Feedback</span><span class="cls_004"> objects are a dependency of the</span></div>
<div style="position:absolute;left:5.00px;top:439.50px" class="cls_007"><span class="cls_007">FeedbackCollection</span><span class="cls_004"> object and that in turn, is a dependency of the </span><span class="cls_007">FeedbackManager</span><span class="cls_004"> class.</span></div>
<div style="position:absolute;left:5.00px;top:457.50px" class="cls_004"><span class="cls_004">These objects are all tightly coupled, which is usually a bad thing in software development.</span></div>
<div style="position:absolute;left:5.00px;top:475.50px" class="cls_004"><span class="cls_004">However, they are also tightly related by necessity. A </span><span class="cls_007">FeedbackCollection</span><span class="cls_004"> object would be</span></div>
<div style="position:absolute;left:5.00px;top:493.50px" class="cls_004"><span class="cls_004">useless without the </span><span class="cls_007">Feedback</span><span class="cls_004"> objects, as would the </span><span class="cls_007">FeedbackManager</span><span class="cls_004"> object.</span></div>
<div style="position:absolute;left:5.00px;top:511.50px" class="cls_004"><span class="cls_004">In this particular case, these objects require this coupling to make them useful together.</span></div>
<div style="position:absolute;left:5.00px;top:529.50px" class="cls_004"><span class="cls_004">This is called composition, where the individual parts form a whole, but do little on their</span></div>
<div style="position:absolute;left:5.00px;top:547.50px" class="cls_004"><span class="cls_004">own, so it really is no problem for them to be connected in this way.</span></div>
<div style="position:absolute;left:5.00px;top:565.50px" class="cls_004"><span class="cls_004">On the other hand, let's now contemplate the connection between our View Models and our</span></div>
<div style="position:absolute;left:5.00px;top:583.50px" class="cls_004"><span class="cls_004">DAL. Our View Models will definitely need access to some data, so it would at first seem to</span></div>
<div style="position:absolute;left:5.00px;top:601.50px" class="cls_004"><span class="cls_004">make sense to encapsulate a class in our View Models that provides the data that it</span></div>
<div style="position:absolute;left:5.00px;top:619.50px" class="cls_004"><span class="cls_004">requires.</span></div>
<div style="position:absolute;left:5.00px;top:637.50px" class="cls_004"><span class="cls_004">While that would certainly work, it would unfortunately result in the DAL class becoming a</span></div>
<div style="position:absolute;left:5.00px;top:655.50px" class="cls_004"><span class="cls_004">dependent of the View Model class. Moreover, it would permanently couple our View Model</span></div>
<div style="position:absolute;left:5.00px;top:673.50px" class="cls_004"><span class="cls_004">component to the DAL and break the Separation of Concerns that MVVM provides. The</span></div>
<div style="position:absolute;left:5.00px;top:691.50px" class="cls_004"><span class="cls_004">kind of connection that we require in this situation is more like aggregation, where the</span></div>
<div style="position:absolute;left:5.00px;top:709.50px" class="cls_004"><span class="cls_004">individual parts are useful on their own.</span></div>
<div style="position:absolute;left:5.00px;top:727.50px" class="cls_004"><span class="cls_004">In these cases, we want to be able to use the individual components separately and to</span></div>
<div style="position:absolute;left:5.00px;top:745.50px" class="cls_004"><span class="cls_004">avoid any tight coupling between them. Dependency Injection is a tool that we can use to</span></div>
<div style="position:absolute;left:5.00px;top:763.50px" class="cls_004"><span class="cls_004">provide this separation for us. In the absolute simplest terms, Dependency Injection is</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:85012px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background108.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">implemented through the use of interfaces. We've already seen some basic examples of</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">this in the </span><span class="cls_007">DataController</span><span class="cls_004"> class from the </span><span class="cls_006">Separating the Data Access Layer</span><span class="cls_004"> section and</span></div>
<div style="position:absolute;left:5.00px;top:40.50px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">EmailManager</span><span class="cls_004"> example from the previous section.</span></div>
<div style="position:absolute;left:5.00px;top:58.50px" class="cls_004"><span class="cls_004">However, they were very basic examples and there are a variety of ways of improving</span></div>
<div style="position:absolute;left:5.00px;top:76.50px" class="cls_004"><span class="cls_004">them. Many application frameworks will provide the ability for the developers to use</span></div>
<div style="position:absolute;left:5.00px;top:94.50px" class="cls_004"><span class="cls_004">Dependency Injection to inject the dependencies into their classes and we can do the same</span></div>
<div style="position:absolute;left:5.00px;top:112.50px" class="cls_004"><span class="cls_004">with ours. In its simplest form, our </span><span class="cls_007">DependencyManager</span><span class="cls_004"> class will simply need to register the</span></div>
<div style="position:absolute;left:5.00px;top:130.50px" class="cls_004"><span class="cls_004">dependencies and provide a way to resolve them when required. Let's take a look:</span></div>
<div style="position:absolute;left:52.98px;top:153.75px" class="cls_007"><span class="cls_007">using System;</span></div>
<div style="position:absolute;left:52.98px;top:167.25px" class="cls_007"><span class="cls_007">using System.Collections.Generic;</span></div>
<div style="position:absolute;left:52.98px;top:194.25px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.Managers</span></div>
<div style="position:absolute;left:52.98px;top:207.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:221.25px" class="cls_007"><span class="cls_007">public class DependencyManager</span></div>
<div style="position:absolute;left:67.97px;top:234.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:248.25px" class="cls_007"><span class="cls_007">private static DependencyManager instance;</span></div>
<div style="position:absolute;left:82.97px;top:261.75px" class="cls_007"><span class="cls_007">private static Dictionary<Type, Type> registeredDependencies =</span></div>
<div style="position:absolute;left:97.96px;top:275.25px" class="cls_007"><span class="cls_007">new Dictionary<Type, Type>();</span></div>
<div style="position:absolute;left:82.97px;top:302.25px" class="cls_007"><span class="cls_007">private DependencyManager() { }</span></div>
<div style="position:absolute;left:82.97px;top:329.25px" class="cls_007"><span class="cls_007">public static DependencyManager Instance</span></div>
<div style="position:absolute;left:82.97px;top:342.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:356.25px" class="cls_007"><span class="cls_007">get { return instance ?? (instance = new</span></div>
<div style="position:absolute;left:52.98px;top:369.75px" class="cls_007"><span class="cls_007">DependencyManager()); }</span></div>
<div style="position:absolute;left:82.97px;top:383.25px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:410.25px" class="cls_007"><span class="cls_007">public int Count</span></div>
<div style="position:absolute;left:82.97px;top:423.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:437.25px" class="cls_007"><span class="cls_007">get { return registeredDependencies.Count; }</span></div>
<div style="position:absolute;left:82.97px;top:450.75px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:477.75px" class="cls_007"><span class="cls_007">public void ClearRegistrations()</span></div>
<div style="position:absolute;left:82.97px;top:491.25px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:504.75px" class="cls_007"><span class="cls_007">registeredDependencies.Clear();</span></div>
<div style="position:absolute;left:82.97px;top:518.25px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:545.25px" class="cls_007"><span class="cls_007">public void Register<S, T>() where S : class where T : class</span></div>
<div style="position:absolute;left:82.97px;top:558.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:572.25px" class="cls_007"><span class="cls_007">if (!typeof(S).IsInterface) throw new ArgumentException("The</span></div>
<div style="position:absolute;left:52.98px;top:585.75px" class="cls_007"><span class="cls_007">S</span></div>
<div style="position:absolute;left:112.96px;top:599.25px" class="cls_007"><span class="cls_007">generic type parameter of the Register method must be an</span></div>
<div style="position:absolute;left:112.96px;top:612.75px" class="cls_007"><span class="cls_007">interface.", "S");</span></div>
<div style="position:absolute;left:97.96px;top:626.25px" class="cls_007"><span class="cls_007">if (!typeof(S).IsAssignableFrom(typeof(T))) throw</span></div>
<div style="position:absolute;left:112.96px;top:639.75px" class="cls_007"><span class="cls_007">new ArgumentException("The T generic type parameter must be</span></div>
<div style="position:absolute;left:52.98px;top:653.25px" class="cls_007"><span class="cls_007">a</span></div>
<div style="position:absolute;left:112.96px;top:666.75px" class="cls_007"><span class="cls_007">class that implements the interface specified by the S</span></div>
<div style="position:absolute;left:52.98px;top:680.25px" class="cls_007"><span class="cls_007">generic</span></div>
<div style="position:absolute;left:112.96px;top:693.75px" class="cls_007"><span class="cls_007">type parameter.", "T");</span></div>
<div style="position:absolute;left:97.96px;top:707.25px" class="cls_007"><span class="cls_007">if (!registeredDependencies.ContainsKey(typeof(S)))</span></div>
<div style="position:absolute;left:112.96px;top:720.75px" class="cls_007"><span class="cls_007">registeredDependencies.Add(typeof(S), typeof(T));</span></div>
<div style="position:absolute;left:82.97px;top:734.25px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:761.25px" class="cls_007"><span class="cls_007">public T Resolve<T>() where T : class</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:85814px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background109.jpg" width=612 height=792></div>
<div style="position:absolute;left:82.97px;top:3.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:16.50px" class="cls_007"><span class="cls_007">Type type = registeredDependencies[typeof(T)];</span></div>
<div style="position:absolute;left:97.96px;top:30.00px" class="cls_007"><span class="cls_007">return Activator.CreateInstance(type) as T;</span></div>
<div style="position:absolute;left:82.97px;top:43.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:70.50px" class="cls_007"><span class="cls_007">public T Resolve<T>(params object[] args) where T : class</span></div>
<div style="position:absolute;left:82.97px;top:84.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:97.50px" class="cls_007"><span class="cls_007">Type type = registeredDependencies[typeof(T)];</span></div>
<div style="position:absolute;left:97.96px;top:111.00px" class="cls_007"><span class="cls_007">if (args == null || args.Length == 0)</span></div>
<div style="position:absolute;left:112.96px;top:124.50px" class="cls_007"><span class="cls_007">return Activator.CreateInstance(type) as T;</span></div>
<div style="position:absolute;left:97.96px;top:138.00px" class="cls_007"><span class="cls_007">else return Activator.CreateInstance(type, args) as T;</span></div>
<div style="position:absolute;left:82.97px;top:151.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:165.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:178.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:211.50px" class="cls_004"><span class="cls_004">You may have noticed that we are using the Singleton pattern again for this class. In this</span></div>
<div style="position:absolute;left:5.00px;top:229.50px" class="cls_004"><span class="cls_004">case, it fits our requirements exactly again. We want one and only one instance of this class</span></div>
<div style="position:absolute;left:5.00px;top:247.50px" class="cls_004"><span class="cls_004">to be instantiated and we want it to stay alive for as long as the application is running.</span></div>
<div style="position:absolute;left:5.00px;top:265.50px" class="cls_004"><span class="cls_004">When testing, it is used to inject our mock dependencies into the View Models, so it is part</span></div>
<div style="position:absolute;left:5.00px;top:283.50px" class="cls_004"><span class="cls_004">of the framework that enables our Separation of Concerns.</span></div>
<div style="position:absolute;left:5.00px;top:301.50px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">Count</span><span class="cls_004"> property and the </span><span class="cls_007">ClearRegistrations</span><span class="cls_004"> method are more useful for testing than</span></div>
<div style="position:absolute;left:5.00px;top:319.50px" class="cls_004"><span class="cls_004">when running the application and the real action goes on in the </span><span class="cls_007">Register</span><span class="cls_004"> and </span><span class="cls_007">Resolve</span></div>
<div style="position:absolute;left:5.00px;top:337.50px" class="cls_004"><span class="cls_004">methods. The </span><span class="cls_007">Register</span><span class="cls_004"> method registers the interface type represented by the </span><span class="cls_007">S</span><span class="cls_004"> generic</span></div>
<div style="position:absolute;left:5.00px;top:355.50px" class="cls_004"><span class="cls_004">type parameter with the concrete implementation of that interface represented by the</span></div>
<div style="position:absolute;left:5.00px;top:373.50px" class="cls_004"><span class="cls_004">generic type parameter.</span></div>
<div style="position:absolute;left:5.00px;top:391.50px" class="cls_004"><span class="cls_004">As the </span><span class="cls_007">S</span><span class="cls_004"> generic type parameter must be an interface, an </span><span class="cls_007">ArgumentException</span><span class="cls_004"> is thrown at</span></div>
<div style="position:absolute;left:5.00px;top:409.50px" class="cls_004"><span class="cls_004">runtime if the supplied type parameter class is not one. A further check is performed to</span></div>
<div style="position:absolute;left:5.00px;top:427.50px" class="cls_004"><span class="cls_004">ensure that the type specified by the </span><span class="cls_007">T</span><span class="cls_004"> generic type parameter actually implements the</span></div>
<div style="position:absolute;left:5.00px;top:445.50px" class="cls_004"><span class="cls_004">interface specified by the </span><span class="cls_007">S</span><span class="cls_004"> generic type parameter.</span></div>
<div style="position:absolute;left:5.00px;top:463.50px" class="cls_004"><span class="cls_004">The method then verifies that the provided type parameter is not already in the </span><span class="cls_007">Dictionary</span></div>
<div style="position:absolute;left:5.00px;top:481.50px" class="cls_004"><span class="cls_004">and adds it if it is unique in the collection. Therefore, in this particular implementation, we</span></div>
<div style="position:absolute;left:5.00px;top:499.50px" class="cls_004"><span class="cls_004">can only specify a single concrete implementation for each supplied interface. We could</span></div>
<div style="position:absolute;left:5.00px;top:517.50px" class="cls_004"><span class="cls_004">change this to either update the stored reference if an existing type was passed again, or</span></div>
<div style="position:absolute;left:5.00px;top:535.50px" class="cls_004"><span class="cls_004">even to store multiple concrete types for each interface. It all depends on the application</span></div>
<div style="position:absolute;left:5.00px;top:553.50px" class="cls_004"><span class="cls_004">requirements.</span></div>
<div style="position:absolute;left:5.00px;top:571.50px" class="cls_004"><span class="cls_004">Note the generic type constraint declared on this method that ensures the type parameters</span></div>
<div style="position:absolute;left:5.00px;top:589.50px" class="cls_004"><span class="cls_004">will at least be classes. Unfortunately, there is no such constraint that would allow us to</span></div>
<div style="position:absolute;left:5.00px;top:607.50px" class="cls_004"><span class="cls_004">specify that a particular generic type parameter should be an interface. However, this type</span></div>
<div style="position:absolute;left:5.00px;top:625.50px" class="cls_004"><span class="cls_004">of parameter validation should be used where possible, as it helps the users of our</span></div>
<div style="position:absolute;left:5.00px;top:643.50px" class="cls_004"><span class="cls_004">framework to avoid using these methods with inappropriate values.</span></div>
<div style="position:absolute;left:5.00px;top:661.50px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">Resolve</span><span class="cls_004"> methods use some simple reflection to return the concrete implementations of</span></div>
<div style="position:absolute;left:5.00px;top:679.50px" class="cls_004"><span class="cls_004">the interface types represented the generic type parameters used. Again, note the generic</span></div>
<div style="position:absolute;left:5.00px;top:697.50px" class="cls_004"><span class="cls_004">type constraints declared by these two methods, that specify that the type used for the </span><span class="cls_007">T</span></div>
<div style="position:absolute;left:5.00px;top:715.50px" class="cls_004"><span class="cls_004">type parameter must be a class. This is to prevent the </span><span class="cls_007">Activator.CreateInstance</span><span class="cls_004"> methods</span></div>
<div style="position:absolute;left:5.00px;top:733.50px" class="cls_004"><span class="cls_004">from throwing an </span><span class="cls_007">Exception</span><span class="cls_004"> at runtime, if a type that could not be instantiated were used.</span></div>
<div style="position:absolute;left:5.00px;top:751.50px" class="cls_004"><span class="cls_004">The first overload can be used for classes without any constructor parameters and the</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:86616px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background110.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">second has an additional </span><span class="cls_007">params</span><span class="cls_004"> input parameter to pass the parameters to use when</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">instantiating classes that require constructor parameters.</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">DependencyManager</span><span class="cls_004"> class can be setup during application startup, using the</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_007"><span class="cls_007">App.xaml.cs</span><span class="cls_004"> file. To do this, we first need to find the following </span><span class="cls_007">StartupUri</span><span class="cls_004"> property setting</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">in the </span><span class="cls_007">Application</span><span class="cls_004"> declaration at the top of the </span><span class="cls_007">App.xaml</span><span class="cls_004"> file:</span></div>
<div style="position:absolute;left:52.98px;top:99.00px" class="cls_007"><span class="cls_007">StartupUri="MainWindow.xaml"</span></div>
<div style="position:absolute;left:5.00px;top:119.25px" class="cls_004"><span class="cls_004">We then need to replace this </span><span class="cls_007">StartupUri</span><span class="cls_004"> property setting with the following </span><span class="cls_007">Startup</span></div>
<div style="position:absolute;left:5.00px;top:137.25px" class="cls_004"><span class="cls_004">property setting:</span></div>
<div style="position:absolute;left:52.98px;top:160.50px" class="cls_007"><span class="cls_007">Startup="App_Startup"</span></div>
<div style="position:absolute;left:5.00px;top:180.75px" class="cls_004"><span class="cls_004">In this example, </span><span class="cls_007">App_Startup</span><span class="cls_004"> is the name of the initialization method that we want to be</span></div>
<div style="position:absolute;left:5.00px;top:198.75px" class="cls_004"><span class="cls_004">called at startup. Note that as the WPF Framework is no longer starting the </span><span class="cls_007">MainWindow</span></div>
<div style="position:absolute;left:5.00px;top:216.75px" class="cls_004"><span class="cls_004">class, it is now our responsibility to do so.</span></div>
<div style="position:absolute;left:52.98px;top:240.00px" class="cls_007"><span class="cls_007">using System.Windows;</span></div>
<div style="position:absolute;left:52.98px;top:253.50px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.Managers;</span></div>
<div style="position:absolute;left:52.98px;top:267.00px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.ViewModels;</span></div>
<div style="position:absolute;left:52.98px;top:280.50px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.ViewModels.Interfaces;</span></div>
<div style="position:absolute;left:52.98px;top:307.50px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName</span></div>
<div style="position:absolute;left:52.98px;top:321.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:334.50px" class="cls_007"><span class="cls_007">public partial class App : Application</span></div>
<div style="position:absolute;left:67.97px;top:348.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:361.50px" class="cls_007"><span class="cls_007">public void App_Startup(object sender, StartupEventArgs e)</span></div>
<div style="position:absolute;left:82.97px;top:375.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:388.50px" class="cls_007"><span class="cls_007">RegisterDependencies();</span></div>
<div style="position:absolute;left:97.96px;top:402.00px" class="cls_007"><span class="cls_007">new MainWindow().Show();</span></div>
<div style="position:absolute;left:82.97px;top:415.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:442.50px" class="cls_007"><span class="cls_007">private void RegisterDependencies()</span></div>
<div style="position:absolute;left:82.97px;top:456.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:469.50px" class="cls_007"><span class="cls_007">DependencyManager.Instance.ClearRegistrations();</span></div>
<div style="position:absolute;left:97.96px;top:483.00px" class="cls_007"><span class="cls_007">DependencyManager.Instance.Register<IDataProvider,</span></div>
<div style="position:absolute;left:112.96px;top:496.50px" class="cls_007"><span class="cls_007">ApplicationDataProvider>();</span></div>
<div style="position:absolute;left:97.96px;top:510.00px" class="cls_007"><span class="cls_007">DependencyManager.Instance.Register<IEmailManager,</span></div>
<div style="position:absolute;left:52.98px;top:523.50px" class="cls_007"><span class="cls_007">EmailManager>();</span></div>
<div style="position:absolute;left:97.96px;top:537.00px" class="cls_007"><span class="cls_007">DependencyManager.Instance.Register<IExcelManager,</span></div>
<div style="position:absolute;left:52.98px;top:550.50px" class="cls_007"><span class="cls_007">ExcelManager>();</span></div>
<div style="position:absolute;left:97.96px;top:564.00px" class="cls_007"><span class="cls_007">DependencyManager.Instance.Register<IWindowManager,</span></div>
<div style="position:absolute;left:52.98px;top:577.50px" class="cls_007"><span class="cls_007">WindowManager>();</span></div>
<div style="position:absolute;left:82.97px;top:591.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:604.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:618.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:638.25px" class="cls_004"><span class="cls_004">When we want to inject these dependencies into a View Model in the application at runtime,</span></div>
<div style="position:absolute;left:5.00px;top:656.25px" class="cls_004"><span class="cls_004">we could use the </span><span class="cls_007">DependencyManager</span><span class="cls_004"> class like this:</span></div>
<div style="position:absolute;left:52.98px;top:679.50px" class="cls_007"><span class="cls_007">UsersViewModel viewModel =</span></div>
<div style="position:absolute;left:67.97px;top:693.00px" class="cls_007"><span class="cls_007">new</span></div>
<div style="position:absolute;left:52.98px;top:706.50px" class="cls_007"><span class="cls_007">UsersViewModel(DependencyManager.Instance.Resolve<IEmailManager>(),</span></div>
<div style="position:absolute;left:67.97px;top:720.00px" class="cls_007"><span class="cls_007">DependencyManager.Instance.Resolve<IExcelManager>(),</span></div>
<div style="position:absolute;left:67.97px;top:733.50px" class="cls_007"><span class="cls_007">DependencyManager.Instance.Resolve<IWindowManager>());</span></div>
<div style="position:absolute;left:5.00px;top:753.75px" class="cls_004"><span class="cls_004">The real beauty of this system is that when testing our View Models, we can register our</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:87418px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background111.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">mock manager classes instead. The same preceding code will then resolve the interfaces</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">to their mock concrete implementations, thereby freeing our View Models from their actual</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">dependencies.</span></div>
<div style="position:absolute;left:52.98px;top:63.00px" class="cls_007"><span class="cls_007">private void RegisterMockDependencies()</span></div>
<div style="position:absolute;left:52.98px;top:76.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:90.00px" class="cls_007"><span class="cls_007">DependencyManager.Instance.ClearRegistrations();</span></div>
<div style="position:absolute;left:67.97px;top:103.50px" class="cls_007"><span class="cls_007">DependencyManager.Instance.Register<IDataProvider,</span></div>
<div style="position:absolute;left:52.98px;top:117.00px" class="cls_007"><span class="cls_007">MockDataProvider>();</span></div>
<div style="position:absolute;left:67.97px;top:130.50px" class="cls_007"><span class="cls_007">DependencyManager.Instance.Register<IEmailManager,</span></div>
<div style="position:absolute;left:52.98px;top:144.00px" class="cls_007"><span class="cls_007">MockEmailManager>();</span></div>
<div style="position:absolute;left:67.97px;top:157.50px" class="cls_007"><span class="cls_007">DependencyManager.Instance.Register<IExcelManager,</span></div>
<div style="position:absolute;left:52.98px;top:171.00px" class="cls_007"><span class="cls_007">MockExcelManager>();</span></div>
<div style="position:absolute;left:67.97px;top:184.50px" class="cls_007"><span class="cls_007">DependencyManager.Instance.Register<IWindowManager,</span></div>
<div style="position:absolute;left:52.98px;top:198.00px" class="cls_007"><span class="cls_007">MockWindowManager>();</span></div>
<div style="position:absolute;left:52.98px;top:211.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:231.75px" class="cls_004"><span class="cls_004">We've now seen the code that enables us to swap out our dependent classes with mock</span></div>
<div style="position:absolute;left:5.00px;top:249.75px" class="cls_004"><span class="cls_004">implementations when we are testing our application. However, we've also seen that not all</span></div>
<div style="position:absolute;left:5.00px;top:267.75px" class="cls_004"><span class="cls_004">of our manager classes will require this. So what exactly represents a dependency? Let's</span></div>
<div style="position:absolute;left:5.00px;top:285.75px" class="cls_004"><span class="cls_004">take a look at a simple example involving a UI popup message box:</span></div>
<div style="position:absolute;left:52.98px;top:309.00px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.DataModels.Enums;</span></div>
<div style="position:absolute;left:52.98px;top:336.00px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.Managers.Interfaces</span></div>
<div style="position:absolute;left:52.98px;top:349.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:363.00px" class="cls_007"><span class="cls_007">public interface IWindowManager</span></div>
<div style="position:absolute;left:67.97px;top:376.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:390.00px" class="cls_007"><span class="cls_007">MessageBoxButtonSelection ShowMessageBox(string message,</span></div>
<div style="position:absolute;left:97.96px;top:403.50px" class="cls_007"><span class="cls_007">string title, MessageBoxButton buttons, MessageBoxIcon icon);</span></div>
<div style="position:absolute;left:67.97px;top:417.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:430.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:463.50px" class="cls_004"><span class="cls_004">Here we have an interface that declares a single method. This is the method that the</span></div>
<div style="position:absolute;left:5.00px;top:481.50px" class="cls_004"><span class="cls_004">developers will call from the View Model classes when they need to display a message box</span></div>
<div style="position:absolute;left:5.00px;top:499.50px" class="cls_004"><span class="cls_004">in the UI. It will use a real </span><span class="cls_007">MessageBox</span><span class="cls_004"> object during runtime, but this uses a number of</span></div>
<div style="position:absolute;left:5.00px;top:517.50px" class="cls_004"><span class="cls_004">enumerations from the </span><span class="cls_007">System.Windows</span><span class="cls_004"> namespace.</span></div>
<div style="position:absolute;left:5.00px;top:535.50px" class="cls_004"><span class="cls_004">We want to avoid interacting with these enumeration instances in our View Models, as that</span></div>
<div style="position:absolute;left:5.00px;top:553.50px" class="cls_004"><span class="cls_004">will require adding a reference to the </span><span class="cls_007">PresentationFramework</span><span class="cls_004"> assembly and tie our View</span></div>
<div style="position:absolute;left:5.00px;top:571.50px" class="cls_004"><span class="cls_004">Models to part of our Views component.</span></div>
<div style="position:absolute;left:5.00px;top:589.50px" class="cls_004"><span class="cls_004">We therefore need to abstract them from our interface method definition. In this case, we</span></div>
<div style="position:absolute;left:5.00px;top:607.50px" class="cls_004"><span class="cls_004">have simply replaced the enumerations from the </span><span class="cls_007">PresentationFramework</span><span class="cls_004"> assembly with</span></div>
<div style="position:absolute;left:5.00px;top:625.50px" class="cls_004"><span class="cls_004">custom enumerations from our domain that merely replicate the original values. As such,</span></div>
<div style="position:absolute;left:5.00px;top:643.50px" class="cls_004"><span class="cls_004">there is little point in showing the code for these custom enumerations here.</span></div>
<div style="position:absolute;left:5.00px;top:661.50px" class="cls_004"><span class="cls_004">While it's never a good idea to duplicate code, it's an even worse idea to add a UI</span></div>
<div style="position:absolute;left:5.00px;top:679.50px" class="cls_004"><span class="cls_004">assembly like the </span><span class="cls_007">PresentationFramework</span><span class="cls_004"> assembly to our </span><span class="cls_007">ViewModels</span><span class="cls_004"> project. By</span></div>
<div style="position:absolute;left:5.00px;top:697.50px" class="cls_004"><span class="cls_004">encapsulating this assembly within the </span><span class="cls_007">Managers</span><span class="cls_004"> project and converting its enumerations,</span></div>
<div style="position:absolute;left:5.00px;top:715.50px" class="cls_004"><span class="cls_004">we can expose the functionality that we need from it without tying it to our View Models.</span></div>
<div style="position:absolute;left:52.98px;top:738.75px" class="cls_007"><span class="cls_007">using System.Windows;</span></div>
<div style="position:absolute;left:52.98px;top:752.25px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.Managers.Interfaces;</span></div>
<div style="position:absolute;left:52.98px;top:765.75px" class="cls_007"><span class="cls_007">using MessageBoxButton =</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:88220px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background112.jpg" width=612 height=792></div>
<div style="position:absolute;left:67.97px;top:3.00px" class="cls_007"><span class="cls_007">CompanyName.ApplicationName.DataModels.Enums.MessageBoxButton;</span></div>
<div style="position:absolute;left:52.98px;top:16.50px" class="cls_007"><span class="cls_007">using MessageBoxButtonSelection =</span></div>
<div style="position:absolute;left:52.98px;top:43.50px" class="cls_007"><span class="cls_007">CompanyName.ApplicationName.DataModels.Enums.MessageBoxButtonSelect</span></div>
<div style="position:absolute;left:52.98px;top:57.00px" class="cls_007"><span class="cls_007">ion;</span></div>
<div style="position:absolute;left:52.98px;top:70.50px" class="cls_007"><span class="cls_007">using MessageBoxIcon =</span></div>
<div style="position:absolute;left:67.97px;top:84.00px" class="cls_007"><span class="cls_007">CompanyName.ApplicationName.DataModels.Enums.MessageBoxIcon;</span></div>
<div style="position:absolute;left:52.98px;top:111.00px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.Managers</span></div>
<div style="position:absolute;left:52.98px;top:124.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:138.00px" class="cls_007"><span class="cls_007">public class WindowManager : IWindowManager</span></div>
<div style="position:absolute;left:67.97px;top:151.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:165.00px" class="cls_007"><span class="cls_007">public MessageBoxButtonSelection ShowMessageBox(string message,</span></div>
<div style="position:absolute;left:97.96px;top:178.50px" class="cls_007"><span class="cls_007">string title, MessageBoxButton buttons, MessageBoxIcon icon)</span></div>
<div style="position:absolute;left:82.97px;top:192.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:205.50px" class="cls_007"><span class="cls_007">System.Windows.MessageBoxButton messageBoxButtons;</span></div>
<div style="position:absolute;left:97.96px;top:219.00px" class="cls_007"><span class="cls_007">switch (buttons)</span></div>
<div style="position:absolute;left:97.96px;top:232.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:112.96px;top:246.00px" class="cls_007"><span class="cls_007">case MessageBoxButton.Ok: messageBoxButtons =</span></div>
<div style="position:absolute;left:127.95px;top:259.50px" class="cls_007"><span class="cls_007">System.Windows.MessageBoxButton.OK; break;</span></div>
<div style="position:absolute;left:112.96px;top:273.00px" class="cls_007"><span class="cls_007">case MessageBoxButton.OkCancel: messageBoxButtons =</span></div>
<div style="position:absolute;left:127.95px;top:286.50px" class="cls_007"><span class="cls_007">System.Windows. MessageBoxButton.OkCancel; break;</span></div>
<div style="position:absolute;left:112.96px;top:300.00px" class="cls_007"><span class="cls_007">case MessageBoxButton.YesNo: messageBoxButtons =</span></div>
<div style="position:absolute;left:127.95px;top:313.50px" class="cls_007"><span class="cls_007">System.Windows.MessageBoxButton.YesNo; break;</span></div>
<div style="position:absolute;left:112.96px;top:327.00px" class="cls_007"><span class="cls_007">case MessageBoxButton.YesNoCancel: messageBoxButtons =</span></div>
<div style="position:absolute;left:127.95px;top:340.50px" class="cls_007"><span class="cls_007">System.Windows.MessageBoxButton.YesNoCancel; break;</span></div>
<div style="position:absolute;left:112.96px;top:354.00px" class="cls_007"><span class="cls_007">default: messageBoxButtons =</span></div>
<div style="position:absolute;left:127.95px;top:367.50px" class="cls_007"><span class="cls_007">System.Windows.MessageBoxButton.OKCancel; break;</span></div>
<div style="position:absolute;left:97.96px;top:381.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:97.96px;top:394.50px" class="cls_007"><span class="cls_007">MessageBoxImage messageBoxImage;</span></div>
<div style="position:absolute;left:97.96px;top:408.00px" class="cls_007"><span class="cls_007">switch (icon)</span></div>
<div style="position:absolute;left:97.96px;top:421.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:112.96px;top:435.00px" class="cls_007"><span class="cls_007">case MessageBoxIcon.Asterisk:</span></div>
<div style="position:absolute;left:127.95px;top:448.50px" class="cls_007"><span class="cls_007">messageBoxImage = MessageBoxImage.Asterisk; break;</span></div>
<div style="position:absolute;left:112.96px;top:462.00px" class="cls_007"><span class="cls_007">case MessageBoxIcon.Error:</span></div>
<div style="position:absolute;left:127.95px;top:475.50px" class="cls_007"><span class="cls_007">messageBoxImage = MessageBoxImage.Error; break;</span></div>
<div style="position:absolute;left:112.96px;top:489.00px" class="cls_007"><span class="cls_007">case MessageBoxIcon.Exclamation:</span></div>
<div style="position:absolute;left:127.95px;top:502.50px" class="cls_007"><span class="cls_007">messageBoxImage = MessageBoxImage.Exclamation; break;</span></div>
<div style="position:absolute;left:112.96px;top:516.00px" class="cls_007"><span class="cls_007">case MessageBoxIcon.Hand:</span></div>
<div style="position:absolute;left:127.95px;top:529.50px" class="cls_007"><span class="cls_007">messageBoxImage = MessageBoxImage.Hand; break;</span></div>
<div style="position:absolute;left:112.96px;top:543.00px" class="cls_007"><span class="cls_007">case MessageBoxIcon.Information:</span></div>
<div style="position:absolute;left:127.95px;top:556.50px" class="cls_007"><span class="cls_007">messageBoxImage = MessageBoxImage.Information; break;</span></div>
<div style="position:absolute;left:112.96px;top:570.00px" class="cls_007"><span class="cls_007">case MessageBoxIcon.None:</span></div>
<div style="position:absolute;left:127.95px;top:583.50px" class="cls_007"><span class="cls_007">messageBoxImage = MessageBoxImage.None; break;</span></div>
<div style="position:absolute;left:112.96px;top:597.00px" class="cls_007"><span class="cls_007">case MessageBoxIcon.Question:</span></div>
<div style="position:absolute;left:127.95px;top:610.50px" class="cls_007"><span class="cls_007">messageBoxImage = MessageBoxImage.Question; break;</span></div>
<div style="position:absolute;left:112.96px;top:624.00px" class="cls_007"><span class="cls_007">case MessageBoxIcon.Stop:</span></div>
<div style="position:absolute;left:127.95px;top:637.50px" class="cls_007"><span class="cls_007">messageBoxImage = MessageBoxImage.Stop; break;</span></div>
<div style="position:absolute;left:112.96px;top:651.00px" class="cls_007"><span class="cls_007">case MessageBoxIcon.Warning:</span></div>
<div style="position:absolute;left:127.95px;top:664.50px" class="cls_007"><span class="cls_007">messageBoxImage = MessageBoxImage.Warning; break;</span></div>
<div style="position:absolute;left:112.96px;top:678.00px" class="cls_007"><span class="cls_007">default: messageBoxImage = MessageBoxImage.Stop; break;</span></div>
<div style="position:absolute;left:97.96px;top:691.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:97.96px;top:705.00px" class="cls_007"><span class="cls_007">MessageBoxButtonSelection messageBoxButtonSelection =</span></div>
<div style="position:absolute;left:112.96px;top:718.50px" class="cls_007"><span class="cls_007">MessageBoxButtonSelection.None;</span></div>
<div style="position:absolute;left:97.96px;top:732.00px" class="cls_007"><span class="cls_007">switch (MessageBox.Show(message, title, messageBoxButtons,</span></div>
<div style="position:absolute;left:112.96px;top:745.50px" class="cls_007"><span class="cls_007">messageBoxImage))</span></div>
<div style="position:absolute;left:97.96px;top:759.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:112.96px;top:772.50px" class="cls_007"><span class="cls_007">case MessageBoxResult.Cancel: messageBoxButtonSelection =</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:89022px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background113.jpg" width=612 height=792></div>
<div style="position:absolute;left:127.95px;top:3.00px" class="cls_007"><span class="cls_007">MessageBoxButtonSelection.Cancel; break;</span></div>
<div style="position:absolute;left:112.96px;top:16.50px" class="cls_007"><span class="cls_007">case MessageBoxResult.No: messageBoxButtonSelection =</span></div>
<div style="position:absolute;left:127.95px;top:30.00px" class="cls_007"><span class="cls_007">MessageBoxButtonSelection.No; break;</span></div>
<div style="position:absolute;left:112.96px;top:43.50px" class="cls_007"><span class="cls_007">case MessageBoxResult.OK: messageBoxButtonSelection =</span></div>
<div style="position:absolute;left:127.95px;top:57.00px" class="cls_007"><span class="cls_007">MessageBoxButtonSelection.Ok; break;</span></div>
<div style="position:absolute;left:112.96px;top:70.50px" class="cls_007"><span class="cls_007">case MessageBoxResult.Yes: messageBoxButtonSelection =</span></div>
<div style="position:absolute;left:127.95px;top:84.00px" class="cls_007"><span class="cls_007">MessageBoxButtonSelection.Yes; break;</span></div>
<div style="position:absolute;left:97.96px;top:97.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:97.96px;top:111.00px" class="cls_007"><span class="cls_007">return messageBoxButtonSelection;</span></div>
<div style="position:absolute;left:82.97px;top:124.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:138.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:151.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:184.50px" class="cls_004"><span class="cls_004">We start with our </span><span class="cls_007">using</span><span class="cls_004"> directives and see further examples of using alias directives. In this</span></div>
<div style="position:absolute;left:5.00px;top:202.50px" class="cls_004"><span class="cls_004">case, we created some enumeration classes with the same names as those from the</span></div>
<div style="position:absolute;left:5.00px;top:220.50px" class="cls_007"><span class="cls_007">System.Windows</span><span class="cls_004"> namespace. To avoid the conflicts that we would have caused by adding a</span></div>
<div style="position:absolute;left:5.00px;top:238.50px" class="cls_004"><span class="cls_004">standard </span><span class="cls_007">using</span><span class="cls_004"> directive for our </span><span class="cls_007">CompanyName.ApplicationName.DataModels.Enums</span></div>
<div style="position:absolute;left:5.00px;top:256.50px" class="cls_004"><span class="cls_004">namespace, we add aliases to enable us to work with just the types from our namespace</span></div>
<div style="position:absolute;left:5.00px;top:274.50px" class="cls_004"><span class="cls_004">that we require.</span></div>
<div style="position:absolute;left:5.00px;top:292.50px" class="cls_004"><span class="cls_004">After this, our </span><span class="cls_007">WindowManager</span><span class="cls_004"> class simply converts the UI-related enumeration values to</span></div>
<div style="position:absolute;left:5.00px;top:310.50px" class="cls_004"><span class="cls_004">and from our custom enumerations, so that we can use the functionality of the message</span></div>
<div style="position:absolute;left:5.00px;top:328.50px" class="cls_004"><span class="cls_004">box, but not be tied to its implementation. Imagine a situation where we need to use this to</span></div>
<div style="position:absolute;left:5.00px;top:346.50px" class="cls_004"><span class="cls_004">output an error message.</span></div>
<div style="position:absolute;left:52.98px;top:369.75px" class="cls_007"><span class="cls_007">WindowManager.ShowMessageBox(errorMessage, "Error",</span></div>
<div style="position:absolute;left:52.98px;top:383.25px" class="cls_007"><span class="cls_007">MessageBoxButton.Ok,</span></div>
<div style="position:absolute;left:67.97px;top:396.75px" class="cls_007"><span class="cls_007">MessageBoxIcon.Error);</span></div>
<div style="position:absolute;left:5.00px;top:417.00px" class="cls_004"><span class="cls_004">When execution reaches this point, a message box will pop up, displaying an error message</span></div>
<div style="position:absolute;left:5.00px;top:435.00px" class="cls_004"><span class="cls_004">with an error icon and heading. The application will freeze at this point while waiting for user</span></div>
<div style="position:absolute;left:5.00px;top:453.00px" class="cls_004"><span class="cls_004">feedback and if the user does not click a button on the popup, it will remain frozen</span></div>
<div style="position:absolute;left:5.00px;top:471.00px" class="cls_004"><span class="cls_004">indefinitely. If execution reaches this point during a unit test and there is no user to click the</span></div>
<div style="position:absolute;left:5.00px;top:489.00px" class="cls_004"><span class="cls_004">button, then our test will freeze indefinitely and the test will never complete.</span></div>
<div style="position:absolute;left:5.00px;top:507.00px" class="cls_004"><span class="cls_004">In this example, the </span><span class="cls_007">WindowManager</span><span class="cls_004"> class is dependent upon having a user present to</span></div>
<div style="position:absolute;left:5.00px;top:525.00px" class="cls_004"><span class="cls_004">interact with it. Therefore, if the View Models used this class directly, they would also have</span></div>
<div style="position:absolute;left:5.00px;top:543.00px" class="cls_004"><span class="cls_004">the same dependency. Other classes might have a dependency on an e-mail server,</span></div>
<div style="position:absolute;left:5.00px;top:561.00px" class="cls_004"><span class="cls_004">database, or other type of resource, for example. These are the types of classes that the</span></div>
<div style="position:absolute;left:5.00px;top:579.00px" class="cls_004"><span class="cls_004">View Models should only interact with via interfaces.</span></div>
<div style="position:absolute;left:5.00px;top:597.00px" class="cls_004"><span class="cls_004">In doing so, we provide the ability to use our components independently from each other.</span></div>
<div style="position:absolute;left:5.00px;top:615.00px" class="cls_004"><span class="cls_004">Using our </span><span class="cls_007">IWindowManager</span><span class="cls_004"> interface, we are able to use our </span><span class="cls_007">ShowMessageBox</span><span class="cls_004"> method</span></div>
<div style="position:absolute;left:5.00px;top:633.00px" class="cls_004"><span class="cls_004">independently of the end users. In this way, we are able to break the user dependency and</span></div>
<div style="position:absolute;left:5.00px;top:651.00px" class="cls_004"><span class="cls_004">run our unit tests without them. Our mock implementation of the interface can simply return</span></div>
<div style="position:absolute;left:5.00px;top:669.00px" class="cls_004"><span class="cls_004">a positive response each time and the program execution can continue unheeded.</span></div>
<div style="position:absolute;left:52.98px;top:692.25px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.DataModels.Enums;</span></div>
<div style="position:absolute;left:52.98px;top:705.75px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.Managers.Interfaces;</span></div>
<div style="position:absolute;left:52.98px;top:732.75px" class="cls_007"><span class="cls_007">namespace Test.CompanyName.ApplicationName.Mocks.Managers</span></div>
<div style="position:absolute;left:52.98px;top:746.25px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:759.75px" class="cls_007"><span class="cls_007">public class MockWindowManager : IWindowManager</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:89824px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background114.jpg" width=612 height=792></div>
<div style="position:absolute;left:67.97px;top:3.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:16.50px" class="cls_007"><span class="cls_007">public MessageBoxButtonSelection ShowMessageBox(string message,</span></div>
<div style="position:absolute;left:97.96px;top:30.00px" class="cls_007"><span class="cls_007">string title, MessageBoxButton buttons, MessageBoxIcon icon)</span></div>
<div style="position:absolute;left:82.97px;top:43.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:57.00px" class="cls_007"><span class="cls_007">switch (buttons)</span></div>
<div style="position:absolute;left:97.96px;top:70.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:112.96px;top:84.00px" class="cls_007"><span class="cls_007">case MessageBoxButton.Ok:</span></div>
<div style="position:absolute;left:112.96px;top:97.50px" class="cls_007"><span class="cls_007">case MessageBoxButton.OkCancel:</span></div>
<div style="position:absolute;left:127.95px;top:111.00px" class="cls_007"><span class="cls_007">return MessageBoxButtonSelection.Ok;</span></div>
<div style="position:absolute;left:112.96px;top:124.50px" class="cls_007"><span class="cls_007">case MessageBoxButton.YesNo:</span></div>
<div style="position:absolute;left:112.96px;top:138.00px" class="cls_007"><span class="cls_007">case MessageBoxButton.YesNoCancel:</span></div>
<div style="position:absolute;left:127.95px;top:151.50px" class="cls_007"><span class="cls_007">return MessageBoxButtonSelection.Yes;</span></div>
<div style="position:absolute;left:112.96px;top:165.00px" class="cls_007"><span class="cls_007">default: return MessageBoxButtonSelection.Ok;</span></div>
<div style="position:absolute;left:97.96px;top:178.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:192.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:205.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:219.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:252.00px" class="cls_004"><span class="cls_004">This simple example shows another method of exposing functionality from a source to our</span></div>
<div style="position:absolute;left:5.00px;top:270.00px" class="cls_004"><span class="cls_004">View Models, but without it becoming a dependency. In this way, we can provide a whole</span></div>
<div style="position:absolute;left:5.00px;top:288.00px" class="cls_004"><span class="cls_004">host and variety of capabilities to our View Models, while still enabling them to function</span></div>
<div style="position:absolute;left:5.00px;top:306.00px" class="cls_004"><span class="cls_004">independently.</span></div>
<div style="position:absolute;left:5.00px;top:324.00px" class="cls_004"><span class="cls_004">We now have the knowledge and tools to build functionality into our application framework</span></div>
<div style="position:absolute;left:5.00px;top:342.00px" class="cls_004"><span class="cls_004">in many different ways, yet our probe into application frameworks is still not quite complete.</span></div>
<div style="position:absolute;left:5.00px;top:360.00px" class="cls_004"><span class="cls_004">One other essential matter is that of connecting our Views with our View Models. We'll</span></div>
<div style="position:absolute;left:5.00px;top:378.00px" class="cls_004"><span class="cls_004">need to decide how the users of our framework should do this, so let's look at some</span></div>
<div style="position:absolute;left:5.00px;top:396.00px" class="cls_004"><span class="cls_004">choices.</span></div>
<div style="position:absolute;left:5.00px;top:413.26px" class="cls_011"><span class="cls_011">Connecting Views with View Models</span></div>
<div style="position:absolute;left:5.00px;top:443.25px" class="cls_004"><span class="cls_004">In WPF, there are several ways to connect our Views to their data sources. We've all seen</span></div>
<div style="position:absolute;left:5.00px;top:461.25px" class="cls_004"><span class="cls_004">examples of the simplest method of a View setting its </span><span class="cls_007">DataContext</span><span class="cls_004"> property to itself in its</span></div>
<div style="position:absolute;left:5.00px;top:479.25px" class="cls_004"><span class="cls_004">code behind.</span></div>
<div style="position:absolute;left:52.98px;top:502.50px" class="cls_007"><span class="cls_007">public partial class MainWindow : Window</span></div>
<div style="position:absolute;left:52.98px;top:516.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:529.50px" class="cls_007"><span class="cls_007">public MainWindow()</span></div>
<div style="position:absolute;left:67.97px;top:543.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:556.50px" class="cls_007"><span class="cls_007">InitializeComponent();</span></div>
<div style="position:absolute;left:82.97px;top:570.00px" class="cls_007"><span class="cls_007">DataContext = this;</span></div>
<div style="position:absolute;left:67.97px;top:583.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:597.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:617.25px" class="cls_004"><span class="cls_004">However, this should only ever be used for quick demonstrations and never in our real-world</span></div>
<div style="position:absolute;left:5.00px;top:635.25px" class="cls_004"><span class="cls_004">applications. If we need to data bind to properties declared in a View's code behind, let's</span></div>
<div style="position:absolute;left:5.00px;top:653.25px" class="cls_004"><span class="cls_004">say for a particular custom </span><span class="cls_007">UserControl</span><span class="cls_004">, then we should use </span><span class="cls_007">RelativeSource</span><span class="cls_004"> bindings</span></div>
<div style="position:absolute;left:5.00px;top:671.25px" class="cls_004"><span class="cls_004">instead. We'll find out more about this in the next chapter, but for now, let's continue looking</span></div>
<div style="position:absolute;left:5.00px;top:689.25px" class="cls_004"><span class="cls_004">at the alternative ways to connect the Views with their data sources.</span></div>
<div style="position:absolute;left:5.00px;top:707.25px" class="cls_004"><span class="cls_004">The next simplest method utilizes the data templating model that is built into the WPF</span></div>
<div style="position:absolute;left:5.00px;top:725.25px" class="cls_004"><span class="cls_004">Framework. This topic will also be covered in much more detail in the next chapter, but in</span></div>
<div style="position:absolute;left:5.00px;top:743.25px" class="cls_004"><span class="cls_004">short, a </span><span class="cls_007">DataTemplate</span><span class="cls_004"> is used to inform the WPF Framework how we want it to render data</span></div>
<div style="position:absolute;left:5.00px;top:761.25px" class="cls_004"><span class="cls_004">objects of a particular type. The simple example below shows how we could define the</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:90626px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background115.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">visual output of our </span><span class="cls_007">User</span><span class="cls_004"> objects:</span></div>
<div style="position:absolute;left:52.98px;top:27.00px" class="cls_007"><span class="cls_007"><DataTemplate DataType="{x:Type DataModels:User}"></span></div>
<div style="position:absolute;left:67.97px;top:40.50px" class="cls_007"><span class="cls_007"><TextBlock Text="{Binding Name}" /></span></div>
<div style="position:absolute;left:52.98px;top:54.00px" class="cls_007"><span class="cls_007"></DataTemplate></span></div>
<div style="position:absolute;left:5.00px;top:74.25px" class="cls_004"><span class="cls_004">In this example, the </span><span class="cls_007">DataType</span><span class="cls_004"> property specifies which type of object this relates to and</span></div>
<div style="position:absolute;left:5.00px;top:92.25px" class="cls_004"><span class="cls_004">therefore, which properties the containing XAML bindings have access to. Keeping it simple</span></div>
<div style="position:absolute;left:5.00px;top:110.25px" class="cls_004"><span class="cls_004">for now, we just output the name of each </span><span class="cls_007">User</span><span class="cls_004"> in this </span><span class="cls_007">DataTemplate</span><span class="cls_004">. When we data bind</span></div>
<div style="position:absolute;left:5.00px;top:128.25px" class="cls_004"><span class="cls_004">one or more </span><span class="cls_007">User</span><span class="cls_004"> objects to a UI control that is in scope of this </span><span class="cls_007">DataTemplate</span><span class="cls_004">, they will</span></div>
<div style="position:absolute;left:5.00px;top:146.25px" class="cls_004"><span class="cls_004">each be rendered by the WPF Framework as a </span><span class="cls_007">TextBlock</span><span class="cls_004"> that specifies their name.</span></div>
<div style="position:absolute;left:5.00px;top:164.25px" class="cls_004"><span class="cls_004">When the rendering engine of the WPF Framework comes across a custom data object, it</span></div>
<div style="position:absolute;left:5.00px;top:182.25px" class="cls_004"><span class="cls_004">looks for a </span><span class="cls_007">DataTemplate</span><span class="cls_004"> that has been declared for its type and if it finds one, it renders</span></div>
<div style="position:absolute;left:5.00px;top:200.25px" class="cls_004"><span class="cls_004">the object according to the XAML contained within the relevant template. This means that</span></div>
<div style="position:absolute;left:5.00px;top:218.25px" class="cls_004"><span class="cls_004">we can create a </span><span class="cls_007">DataTemplate</span><span class="cls_004"> for our View Model classes that simply specifies their</span></div>
<div style="position:absolute;left:5.00px;top:236.25px" class="cls_004"><span class="cls_004">related View classes as the rendering output.</span></div>
<div style="position:absolute;left:52.98px;top:259.50px" class="cls_007"><span class="cls_007"><DataTemplate DataType="{x:Type ViewModels:UsersViewModel}"></span></div>
<div style="position:absolute;left:67.97px;top:273.00px" class="cls_007"><span class="cls_007"><Views:UsersView /></span></div>
<div style="position:absolute;left:52.98px;top:286.50px" class="cls_007"><span class="cls_007"></DataTemplate></span></div>
<div style="position:absolute;left:5.00px;top:306.75px" class="cls_004"><span class="cls_004">In this example, we have specified that when the WPF Framework sees an instance of our</span></div>
<div style="position:absolute;left:5.00px;top:324.75px" class="cls_007"><span class="cls_007">UserViewModel</span><span class="cls_004"> class, it should render it as one of our </span><span class="cls_007">UserView</span><span class="cls_004"> classes. At this point, it will</span></div>
<div style="position:absolute;left:5.00px;top:342.75px" class="cls_004"><span class="cls_004">set our View Model instance to the </span><span class="cls_007">DataContext</span><span class="cls_004"> property of the related View implicitly. The</span></div>
<div style="position:absolute;left:5.00px;top:360.75px" class="cls_004"><span class="cls_004">only downside to this method is minimal and is that we have to add a new </span><span class="cls_007">DataTemplate</span><span class="cls_004"> to</span></div>
<div style="position:absolute;left:5.00px;top:378.75px" class="cls_004"><span class="cls_004">our </span><span class="cls_007">App.xaml</span><span class="cls_004"> file for each of our View-View Model pairs.</span></div>
<div style="position:absolute;left:5.00px;top:396.75px" class="cls_004"><span class="cls_004">This method of connection works View Model first, where we supply the View Model</span></div>
<div style="position:absolute;left:5.00px;top:414.75px" class="cls_004"><span class="cls_004">instance and the WPF Framework takes care of the rest. In these cases, we typically use a</span></div>
<div style="position:absolute;left:5.00px;top:432.75px" class="cls_007"><span class="cls_007">ContentControl</span><span class="cls_004"> that has its </span><span class="cls_007">Content</span><span class="cls_004"> property data bound to a </span><span class="cls_007">ViewModel</span><span class="cls_004"> property, which</span></div>
<div style="position:absolute;left:5.00px;top:450.75px" class="cls_004"><span class="cls_004">the application View Models are set to. The WPF Framework notes the type of the View</span></div>
<div style="position:absolute;left:5.00px;top:468.75px" class="cls_004"><span class="cls_004">Model that is set and renders it according to its specified </span><span class="cls_007">DataTemplate</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:52.98px;top:492.00px" class="cls_007"><span class="cls_007">private BaseViewModel viewModel;</span></div>
<div style="position:absolute;left:52.98px;top:519.00px" class="cls_007"><span class="cls_007">public BaseViewModel ViewModel</span></div>
<div style="position:absolute;left:52.98px;top:532.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:546.00px" class="cls_007"><span class="cls_007">get { return viewModel; }</span></div>
<div style="position:absolute;left:67.97px;top:559.50px" class="cls_007"><span class="cls_007">set { viewModel = value; NotifyPropertyChanged(); }</span></div>
<div style="position:absolute;left:52.98px;top:573.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:627.00px" class="cls_007"><span class="cls_007">ViewModel = new UserViewModel();</span></div>
<div style="position:absolute;left:52.98px;top:681.00px" class="cls_007"><span class="cls_007"><ContentControl Content="{Binding ViewModel}" /></span></div>
<div style="position:absolute;left:5.00px;top:701.25px" class="cls_004"><span class="cls_004">This is the preferred version of View to View Model connections for many, as the WPF</span></div>
<div style="position:absolute;left:5.00px;top:719.25px" class="cls_004"><span class="cls_004">Framework is left to take care of most of the details. However, there is another way to</span></div>
<div style="position:absolute;left:5.00px;top:737.25px" class="cls_004"><span class="cls_004">construct these connections that adds a layer of abstraction to the process.</span></div>
<div style="position:absolute;left:5.00px;top:755.25px" class="cls_004"><span class="cls_004">For this method, we need to create interfaces for each of our View Models. It's called View</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:91428px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background116.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">Model Location and it's fairly similar to the Dependency Injection example that we have</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">already seen. In fact, we could even use our existing </span><span class="cls_007">DependencyManager</span><span class="cls_004"> to achieve a</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">similar result. Let's take a quick look at that first.</span></div>
<div style="position:absolute;left:52.98px;top:63.00px" class="cls_007"><span class="cls_007">DependencyManager.Instance.Register<IUserViewModel, UserViewModel></span></div>
<div style="position:absolute;left:52.98px;top:76.50px" class="cls_007"><span class="cls_007">();</span></div>
<div style="position:absolute;left:52.98px;top:130.50px" class="cls_007"><span class="cls_007">public partial class UserView : UserControl</span></div>
<div style="position:absolute;left:52.98px;top:144.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:157.50px" class="cls_007"><span class="cls_007">public UserView()</span></div>
<div style="position:absolute;left:67.97px;top:171.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:184.50px" class="cls_007"><span class="cls_007">InitializeComponent();</span></div>
<div style="position:absolute;left:82.97px;top:198.00px" class="cls_007"><span class="cls_007">DataContext =</span></div>
<div style="position:absolute;left:52.98px;top:211.50px" class="cls_007"><span class="cls_007">DependencyManager.Instance.Resolve<IUserViewModel>();</span></div>
<div style="position:absolute;left:67.97px;top:225.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:238.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:292.50px" class="cls_007"><span class="cls_007"><Views:UsersView /></span></div>
<div style="position:absolute;left:5.00px;top:312.75px" class="cls_004"><span class="cls_004">In this example, we associate the </span><span class="cls_007">IUserViewModel</span><span class="cls_004"> interface with the </span><span class="cls_007">UserViewModel</span></div>
<div style="position:absolute;left:5.00px;top:330.75px" class="cls_004"><span class="cls_004">concrete implementation of that interface in some initialization code and later, resolve the</span></div>
<div style="position:absolute;left:5.00px;top:348.75px" class="cls_004"><span class="cls_004">dependency, before setting it as the View's </span><span class="cls_007">DataContext</span><span class="cls_004"> value. After declaring our Views in</span></div>
<div style="position:absolute;left:5.00px;top:366.75px" class="cls_004"><span class="cls_004">the XAML, they automatically hook themselves up to their related View Models at runtime.</span></div>
<div style="position:absolute;left:5.00px;top:384.75px" class="cls_004"><span class="cls_004">This method of connecting Views to View Models works View first, where we declare the</span></div>
<div style="position:absolute;left:5.00px;top:402.75px" class="cls_004"><span class="cls_004">View and it instantiates its own View Model and sets its own </span><span class="cls_007">DataContext</span><span class="cls_004">. The downside</span></div>
<div style="position:absolute;left:5.00px;top:420.75px" class="cls_004"><span class="cls_004">with this method is that we have to create an interface for all of our View Models and</span></div>
<div style="position:absolute;left:5.00px;top:438.75px" class="cls_004"><span class="cls_004">register and resolve each of them using the </span><span class="cls_007">DependencyManager</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:456.75px" class="cls_004"><span class="cls_004">The main difference between this implementation and that of a View Model Locator is that a</span></div>
<div style="position:absolute;left:5.00px;top:474.75px" class="cls_004"><span class="cls_004">locator provides a level of abstraction from our Singleton class, which enables us to</span></div>
<div style="position:absolute;left:5.00px;top:492.75px" class="cls_004"><span class="cls_004">indirectly instantiate our View Models from the XAML, without using the code behind. They</span></div>
<div style="position:absolute;left:5.00px;top:510.75px" class="cls_004"><span class="cls_004">also have a little extra specific functionality that enables dummy data to be used at design</span></div>
<div style="position:absolute;left:5.00px;top:528.75px" class="cls_004"><span class="cls_004">time. Let's take a look at the simplest possible example.</span></div>
<div style="position:absolute;left:52.98px;top:552.00px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.Managers;</span></div>
<div style="position:absolute;left:52.98px;top:565.50px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.ViewModels;</span></div>
<div style="position:absolute;left:52.98px;top:579.00px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.ViewModels.Interfaces;</span></div>
<div style="position:absolute;left:52.98px;top:606.00px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.Views.ViewModelLocators</span></div>
<div style="position:absolute;left:52.98px;top:619.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:633.00px" class="cls_007"><span class="cls_007">public class ViewModelLocator</span></div>
<div style="position:absolute;left:67.97px;top:646.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:660.00px" class="cls_007"><span class="cls_007">public IUserViewModel UserViewModel</span></div>
<div style="position:absolute;left:82.97px;top:673.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:687.00px" class="cls_007"><span class="cls_007">get { return</span></div>
<div style="position:absolute;left:52.98px;top:700.50px" class="cls_007"><span class="cls_007">DependencyManager.Instance.Resolve<IUserViewModel>(); }</span></div>
<div style="position:absolute;left:82.97px;top:714.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:727.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:741.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:761.25px" class="cls_004"><span class="cls_004">Here we have a very basic View Model Locator, that simply locates a single View Model. It</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:92230px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background117.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">is important that this View Model class has an empty constructor, so that it can be</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">instantiated from the XAML. Let's see how we can do this:</span></div>
<div style="position:absolute;left:52.98px;top:45.00px" class="cls_007"><span class="cls_007"><UserControl x:Class="CompanyName.ApplicationName.Views.UserView"</span></div>
<div style="position:absolute;left:67.97px;top:58.50px" class="cls_007"><span class="cls_007">xmlns="</span><A HREF="http://schemas.microsoft.com/winfx/2006/xaml/presentation"/">http://schemas.microsoft.com/winfx/2006/xaml/presentation"</A> </div>
<div style="position:absolute;left:67.97px;top:72.00px" class="cls_007"><span class="cls_007">xmlns:x="</span><A HREF="http://schemas.microsoft.com/winfx/2006/xaml"/">http://schemas.microsoft.com/winfx/2006/xaml"</A> </div>
<div style="position:absolute;left:67.97px;top:85.50px" class="cls_007"><span class="cls_007">xmlns:d="</span><A HREF="http://schemas.microsoft.com/expression/blend/2008"/">http://schemas.microsoft.com/expression/blend/2008"</A> </div>
<div style="position:absolute;left:67.97px;top:99.00px" class="cls_007"><span class="cls_007">xmlns:mc="</span><A HREF="http://schemas.openxmlformats.org/markup-/">http://schemas.openxmlformats.org/markup-</A> </div>
<div style="position:absolute;left:52.98px;top:112.50px" class="cls_007"><span class="cls_007">compatibility/2006"</span></div>
<div style="position:absolute;left:67.97px;top:126.00px" class="cls_007"><span class="cls_007">xmlns:ViewModelLocators="clr-namespace:</span></div>
<div style="position:absolute;left:82.97px;top:139.50px" class="cls_007"><span class="cls_007">CompanyName.ApplicationName.Views.ViewModelLocators"</span></div>
<div style="position:absolute;left:67.97px;top:153.00px" class="cls_007"><span class="cls_007">mc:Ignorable="d" Height="30" Width="300"></span></div>
<div style="position:absolute;left:67.97px;top:166.50px" class="cls_007"><span class="cls_007"><UserControl.Resources></span></div>
<div style="position:absolute;left:82.97px;top:180.00px" class="cls_007"><span class="cls_007"><ViewModelLocators:ViewModelLocator x:Key="ViewModelLocator" /></span></div>
<div style="position:absolute;left:67.97px;top:193.50px" class="cls_007"><span class="cls_007"></UserControl.Resources></span></div>
<div style="position:absolute;left:67.97px;top:207.00px" class="cls_007"><span class="cls_007"><UserControl.DataContext></span></div>
<div style="position:absolute;left:82.97px;top:220.50px" class="cls_007"><span class="cls_007"><Binding Path="UserViewModel"</span></div>
<div style="position:absolute;left:97.96px;top:234.00px" class="cls_007"><span class="cls_007">Source="{StaticResource ViewModelLocator}" /></span></div>
<div style="position:absolute;left:67.97px;top:247.50px" class="cls_007"><span class="cls_007"></UserControl.DataContext></span></div>
<div style="position:absolute;left:67.97px;top:261.00px" class="cls_007"><span class="cls_007"><TextBlock Text="{Binding User.Name}" /></span></div>
<div style="position:absolute;left:52.98px;top:274.50px" class="cls_007"><span class="cls_007"></UserControl></span></div>
<div style="position:absolute;left:5.00px;top:307.50px" class="cls_004"><span class="cls_004">As a side note, you may have noticed that our </span><span class="cls_007">ViewModelLocator</span><span class="cls_004"> class has been declared</span></div>
<div style="position:absolute;left:5.00px;top:325.50px" class="cls_004"><span class="cls_004">in the </span><span class="cls_007">Views</span><span class="cls_004"> project. The location of this class is not very important, but it must have</span></div>
<div style="position:absolute;left:5.00px;top:343.50px" class="cls_004"><span class="cls_004">references to both the </span><span class="cls_007">ViewModels</span><span class="cls_004"> and the </span><span class="cls_007">Views</span><span class="cls_004"> projects and this severely limits the</span></div>
<div style="position:absolute;left:5.00px;top:361.50px" class="cls_004"><span class="cls_004">number of projects in which it can reside. Typically, the only projects that will have access to</span></div>
<div style="position:absolute;left:5.00px;top:379.50px" class="cls_004"><span class="cls_004">the classes from both of these projects will be the </span><span class="cls_007">Views</span><span class="cls_004"> project and the startup project.</span></div>
<div style="position:absolute;left:5.00px;top:397.50px" class="cls_004"><span class="cls_004">Getting back to our example, an instance of the </span><span class="cls_007">ViewModelLocator</span><span class="cls_004"> class is declared in the</span></div>
<div style="position:absolute;left:5.00px;top:415.50px" class="cls_004"><span class="cls_004">View's </span><span class="cls_007">Resources</span><span class="cls_004"> section and this will only work if we have a parameterless constructor</span></div>
<div style="position:absolute;left:5.00px;top:433.50px" class="cls_004"><span class="cls_004">(including the default parameterless constructor that is declared for us if we do not explicitly</span></div>
<div style="position:absolute;left:5.00px;top:451.50px" class="cls_004"><span class="cls_004">declare a constructor). Without a parameterless constructor, we will receive an error in the</span></div>
<div style="position:absolute;left:5.00px;top:469.50px" class="cls_004"><span class="cls_004">Visual Studio designer.</span></div>
<div style="position:absolute;left:5.00px;top:487.50px" class="cls_004"><span class="cls_004">Our View sets its own </span><span class="cls_007">DataContext</span><span class="cls_004"> property in XAML this time, using a </span><span class="cls_007">Binding</span><span class="cls_004"> </span><span class="cls_007">Path</span><span class="cls_004"> to the</span></div>
<div style="position:absolute;left:5.00px;top:505.50px" class="cls_007"><span class="cls_007">UserViewModel</span><span class="cls_004"> property from our </span><span class="cls_007">ViewModelLocator</span><span class="cls_004"> resource. The property then utilizes</span></div>
<div style="position:absolute;left:5.00px;top:523.50px" class="cls_004"><span class="cls_004">our </span><span class="cls_007">DependencyManager</span><span class="cls_004"> to resolve the concrete implementation of the </span><span class="cls_007">IUserViewModel</span></div>
<div style="position:absolute;left:5.00px;top:541.50px" class="cls_004"><span class="cls_004">interface and return it for us.</span></div>
<div style="position:absolute;left:5.00px;top:559.50px" class="cls_004"><span class="cls_004">There are other benefits to using this pattern as well though. One problem often faced by</span></div>
<div style="position:absolute;left:5.00px;top:577.50px" class="cls_004"><span class="cls_004">WPF developers is that the Visual Studio WPF Designer cannot resolve the interfaces that</span></div>
<div style="position:absolute;left:5.00px;top:595.50px" class="cls_004"><span class="cls_004">are used back to their concrete implementations, nor can it access the application data</span></div>
<div style="position:absolute;left:5.00px;top:613.50px" class="cls_004"><span class="cls_004">sources during design time. The result of this is that the designer does not typically display</span></div>
<div style="position:absolute;left:5.00px;top:631.50px" class="cls_004"><span class="cls_004">data items that cannot be resolved.</span></div>
<div style="position:absolute;left:5.00px;top:649.50px" class="cls_004"><span class="cls_004">One thing that we can do with our </span><span class="cls_007">ViewModelLocator</span><span class="cls_004"> is to provide mock View Models that</span></div>
<div style="position:absolute;left:5.00px;top:667.50px" class="cls_004"><span class="cls_004">have dummy data returned from their properties that we can use to help visualize our Views</span></div>
<div style="position:absolute;left:5.00px;top:685.50px" class="cls_004"><span class="cls_004">as we construct them. To achieve this, we can make use of the </span><span class="cls_007">IsInDesignMode</span><span class="cls_004"> Attached</span></div>
<div style="position:absolute;left:5.00px;top:703.50px" class="cls_004"><span class="cls_004">Property from the </span><span class="cls_007">DesignerProperties</span><span class="cls_004"> .NET class.</span></div>
<div style="position:absolute;left:52.98px;top:726.75px" class="cls_007"><span class="cls_007">public bool IsDesignTime</span></div>
<div style="position:absolute;left:52.98px;top:740.25px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:753.75px" class="cls_007"><span class="cls_007">get { return</span></div>
<div style="position:absolute;left:82.97px;top:767.25px" class="cls_007"><span class="cls_007">DesignerProperties.GetIsInDesignMode(new DependencyObject()); }</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:93032px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background118.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:3.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:36.00px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">DependencyObject</span><span class="cls_004"> object here is required by the Attached Property and in fact, is the</span></div>
<div style="position:absolute;left:5.00px;top:54.00px" class="cls_004"><span class="cls_004">object that is being checked. As all objects supplied here would return the same value, we</span></div>
<div style="position:absolute;left:5.00px;top:72.00px" class="cls_004"><span class="cls_004">are free to use a new one each time. If we are concerned that this property will be called</span></div>
<div style="position:absolute;left:5.00px;top:90.00px" class="cls_004"><span class="cls_004">more frequently than the garbage collector, we could opt to use a single member instead,</span></div>
<div style="position:absolute;left:5.00px;top:108.00px" class="cls_004"><span class="cls_004">just for this purpose.</span></div>
<div style="position:absolute;left:52.98px;top:131.25px" class="cls_007"><span class="cls_007">private DependencyObject dependencyObject = new DependencyObject();</span></div>
<div style="position:absolute;left:52.98px;top:158.25px" class="cls_007"><span class="cls_007">public bool IsDesignTime</span></div>
<div style="position:absolute;left:52.98px;top:171.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:185.25px" class="cls_007"><span class="cls_007">get { return</span></div>
<div style="position:absolute;left:52.98px;top:198.75px" class="cls_007"><span class="cls_007">DesignerProperties.GetIsInDesignMode(dependencyObject); }</span></div>
<div style="position:absolute;left:52.98px;top:212.25px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:245.25px" class="cls_004"><span class="cls_004">However, if we need a </span><span class="cls_007">DependencyObject</span><span class="cls_004"> object just for this purpose, then we could</span></div>
<div style="position:absolute;left:5.00px;top:263.25px" class="cls_004"><span class="cls_004">simplify things further by extending our </span><span class="cls_007">ViewModelLocator</span><span class="cls_004"> class from the </span><span class="cls_007">DependencyObject</span></div>
<div style="position:absolute;left:5.00px;top:281.25px" class="cls_004"><span class="cls_004">class and use itself as the required parameter. Of course, this would mean that our class</span></div>
<div style="position:absolute;left:5.00px;top:299.25px" class="cls_004"><span class="cls_004">would inherit unwanted properties, so some might prefer to avoid doing this. Let's see how</span></div>
<div style="position:absolute;left:5.00px;top:317.25px" class="cls_004"><span class="cls_004">we could use this property to provide the WPF Designer with mock data at design time:</span></div>
<div style="position:absolute;left:52.98px;top:340.50px" class="cls_007"><span class="cls_007">using System.ComponentModel;</span></div>
<div style="position:absolute;left:52.98px;top:354.00px" class="cls_007"><span class="cls_007">using System.Windows;</span></div>
<div style="position:absolute;left:52.98px;top:367.50px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.Managers;</span></div>
<div style="position:absolute;left:52.98px;top:381.00px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.ViewModels;</span></div>
<div style="position:absolute;left:52.98px;top:394.50px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.ViewModels.Interfaces;</span></div>
<div style="position:absolute;left:52.98px;top:421.50px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.Views.ViewModelLocators</span></div>
<div style="position:absolute;left:52.98px;top:435.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:448.50px" class="cls_007"><span class="cls_007">public class ViewModelLocator : DependencyObject</span></div>
<div style="position:absolute;left:67.97px;top:462.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:475.50px" class="cls_007"><span class="cls_007">public bool IsDesignTime</span></div>
<div style="position:absolute;left:82.97px;top:489.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:502.50px" class="cls_007"><span class="cls_007">get { return DesignerProperties.GetIsInDesignMode(this); }</span></div>
<div style="position:absolute;left:82.97px;top:516.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:543.00px" class="cls_007"><span class="cls_007">public IUserViewModel UserViewModel</span></div>
<div style="position:absolute;left:82.97px;top:556.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:570.00px" class="cls_007"><span class="cls_007">get</span></div>
<div style="position:absolute;left:97.96px;top:583.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:112.96px;top:597.00px" class="cls_007"><span class="cls_007">return IsDesignTime ? new MockUserViewModel() :</span></div>
<div style="position:absolute;left:127.95px;top:610.50px" class="cls_007"><span class="cls_007">DependencyManager.Instance.Resolve<IUserViewModel>();</span></div>
<div style="position:absolute;left:97.96px;top:624.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:637.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:651.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:664.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:684.75px" class="cls_004"><span class="cls_004">If you look at our </span><span class="cls_007">UserViewModel</span><span class="cls_004"> property, you'll see the value that we return is now</span></div>
<div style="position:absolute;left:5.00px;top:702.75px" class="cls_004"><span class="cls_004">dependent upon the value of the </span><span class="cls_007">IsDesignTime</span><span class="cls_004"> property. If we are in design time, for</span></div>
<div style="position:absolute;left:5.00px;top:720.75px" class="cls_004"><span class="cls_004">example when the View file is open in the WPF Designer, then the </span><span class="cls_007">MockUserViewModel</span><span class="cls_004"> class</span></div>
<div style="position:absolute;left:5.00px;top:738.75px" class="cls_004"><span class="cls_004">will be returned. At runtime however, the concrete implementation of our </span><span class="cls_007">IUserViewModel</span></div>
<div style="position:absolute;left:5.00px;top:756.75px" class="cls_004"><span class="cls_004">interface that we registered with the </span><span class="cls_007">DependencyManager</span><span class="cls_004"> will be returned instead.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:93834px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background119.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">MockUserViewModel</span><span class="cls_004"> class will typically hardcode some mock data and return it from its</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">properties when requested. In this manner, the WPF Designer will be able to visualize the</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">data for the developers or designers, while they build the Views.</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">However, each View will require a new property in our locator class and we'll need to copy</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">this conditional operator statement from the preceding code for each. As always in OOP,</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">there is a further abstraction that we could make to hide that implementation away from the</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">developers that will use our framework. We could create a generic base class for our View</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">Model Locator.</span></div>
<div style="position:absolute;left:52.98px;top:153.00px" class="cls_007"><span class="cls_007">using System.ComponentModel;</span></div>
<div style="position:absolute;left:52.98px;top:166.50px" class="cls_007"><span class="cls_007">using System.Windows;</span></div>
<div style="position:absolute;left:52.98px;top:180.00px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.Managers;</span></div>
<div style="position:absolute;left:52.98px;top:207.00px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.Views.ViewModelLocators</span></div>
<div style="position:absolute;left:52.98px;top:220.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:234.00px" class="cls_007"><span class="cls_007">public abstract class BaseViewModelLocator<T> : DependencyObject</span></div>
<div style="position:absolute;left:82.97px;top:247.50px" class="cls_007"><span class="cls_007">where T : class</span></div>
<div style="position:absolute;left:67.97px;top:261.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:274.50px" class="cls_007"><span class="cls_007">private T runtimeViewModel, designTimeViewModel;</span></div>
<div style="position:absolute;left:82.97px;top:301.50px" class="cls_007"><span class="cls_007">protected bool IsDesignTime</span></div>
<div style="position:absolute;left:82.97px;top:315.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:328.50px" class="cls_007"><span class="cls_007">get { return DesignerProperties.GetIsInDesignMode(this); }</span></div>
<div style="position:absolute;left:82.97px;top:342.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:369.00px" class="cls_007"><span class="cls_007">public T ViewModel</span></div>
<div style="position:absolute;left:82.97px;top:382.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:396.00px" class="cls_007"><span class="cls_007">get { return IsDesignTime ?</span></div>
<div style="position:absolute;left:112.96px;top:409.50px" class="cls_007"><span class="cls_007">DesignTimeViewModel : RuntimeViewModel; }</span></div>
<div style="position:absolute;left:82.97px;top:423.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:450.00px" class="cls_007"><span class="cls_007">protected T RuntimeViewModel</span></div>
<div style="position:absolute;left:82.97px;top:463.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:477.00px" class="cls_007"><span class="cls_007">get { return runtimeViewModel ??</span></div>
<div style="position:absolute;left:112.96px;top:490.50px" class="cls_007"><span class="cls_007">(runtimeViewModel = DependencyManager.Instance.Resolve<T></span></div>
<div style="position:absolute;left:52.98px;top:504.00px" class="cls_007"><span class="cls_007">()); }</span></div>
<div style="position:absolute;left:82.97px;top:517.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:544.50px" class="cls_007"><span class="cls_007">protected T DesignTimeViewModel</span></div>
<div style="position:absolute;left:82.97px;top:558.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:571.50px" class="cls_007"><span class="cls_007">set { designTimeViewModel = value; }</span></div>
<div style="position:absolute;left:97.96px;top:585.00px" class="cls_007"><span class="cls_007">get { return designTimeViewModel; }</span></div>
<div style="position:absolute;left:82.97px;top:598.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:612.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:625.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:658.50px" class="cls_004"><span class="cls_004">We start by declaring an abstract class that takes a generic type parameter, which</span></div>
<div style="position:absolute;left:5.00px;top:676.50px" class="cls_004"><span class="cls_004">represents the interface type of the View Model that we are trying to locate. Once again,</span></div>
<div style="position:absolute;left:5.00px;top:694.50px" class="cls_004"><span class="cls_004">note the generic type constraint declared on the generic type parameter that specifies that</span></div>
<div style="position:absolute;left:5.00px;top:712.50px" class="cls_004"><span class="cls_004">the type used must be a class. This is now required because this class calls the </span><span class="cls_007">Resolve</span></div>
<div style="position:absolute;left:5.00px;top:730.50px" class="cls_004"><span class="cls_004">method of the </span><span class="cls_007">DependencyManager</span><span class="cls_004"> class and that has the same constraint declared upon it.</span></div>
<div style="position:absolute;left:5.00px;top:748.50px" class="cls_004"><span class="cls_004">We have two internal members of the relevant type of View Model interface, which back the</span></div>
<div style="position:absolute;left:5.00px;top:766.50px" class="cls_004"><span class="cls_004">properties with the same names. There's one for our runtime View Model and one for our</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:94636px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background120.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">design time View Model. The third View Model property of the same type is the one that we</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">will data bind to from the Views and it uses our </span><span class="cls_007">IsDesignTime</span><span class="cls_004"> property to determine which</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">View Model to return.</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">A nice touch in this class is that it does a lot of the connection work for the developers.</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">They don't need to concern themselves with the implementation of the </span><span class="cls_007">IsDesignTime</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">property and this base class will even attempt to automatically resolve the concrete View</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">Model dependency for the runtime View Model property. Therefore, the developer need</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">only declare the following code for each View model to take advantage of this functionality:</span></div>
<div style="position:absolute;left:52.98px;top:153.00px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.ViewModels;</span></div>
<div style="position:absolute;left:52.98px;top:166.50px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.ViewModels.Interfaces;</span></div>
<div style="position:absolute;left:52.98px;top:193.50px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.Views.ViewModelLocators</span></div>
<div style="position:absolute;left:52.98px;top:207.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:220.50px" class="cls_007"><span class="cls_007">public class UserViewModelLocator :</span></div>
<div style="position:absolute;left:52.98px;top:234.00px" class="cls_007"><span class="cls_007">BaseViewModelLocator<IUserViewModel></span></div>
<div style="position:absolute;left:67.97px;top:247.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:261.00px" class="cls_007"><span class="cls_007">public UserViewModelLocator()</span></div>
<div style="position:absolute;left:82.97px;top:274.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:288.00px" class="cls_007"><span class="cls_007">DesignTimeViewModel = new MockUserViewModel();</span></div>
<div style="position:absolute;left:82.97px;top:301.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:315.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:328.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:348.75px" class="cls_004"><span class="cls_004">It could be setup in the UI with very little difference to our original locator version.</span></div>
<div style="position:absolute;left:52.98px;top:372.00px" class="cls_007"><span class="cls_007"><UserControl x:Class="CompanyName.ApplicationName.Views.UserView"</span></div>
<div style="position:absolute;left:67.97px;top:399.00px" class="cls_007"><span class="cls_007"><UserControl.Resources></span></div>
<div style="position:absolute;left:82.97px;top:412.50px" class="cls_007"><span class="cls_007"><Locators:UserViewModelLocator x:Key="ViewModelLocator" /></span></div>
<div style="position:absolute;left:67.97px;top:426.00px" class="cls_007"><span class="cls_007"></UserControl.Resources></span></div>
<div style="position:absolute;left:67.97px;top:439.50px" class="cls_007"><span class="cls_007"><UserControl.DataContext></span></div>
<div style="position:absolute;left:82.97px;top:453.00px" class="cls_007"><span class="cls_007"><Binding Path="ViewModel" Source="{StaticResource</span></div>
<div style="position:absolute;left:52.98px;top:466.50px" class="cls_007"><span class="cls_007">ViewModelLocator}" /></span></div>
<div style="position:absolute;left:67.97px;top:480.00px" class="cls_007"><span class="cls_007"></UserControl.DataContext></span></div>
<div style="position:absolute;left:52.98px;top:507.00px" class="cls_007"><span class="cls_007"></UserControl></span></div>
<div style="position:absolute;left:5.00px;top:527.25px" class="cls_004"><span class="cls_004">Note that although this should work automatically in newer versions of Visual Studio, you</span></div>
<div style="position:absolute;left:5.00px;top:545.25px" class="cls_004"><span class="cls_004">may need to provide a helping hand to the WPF Designer in older versions. The </span><span class="cls_007">d</span><span class="cls_004"> XML</span></div>
<div style="position:absolute;left:5.00px;top:563.25px" class="cls_004"><span class="cls_004">namespace is used by the Designer and so we can specify a </span><span class="cls_007">DataContext</span><span class="cls_004"> location to it</span></div>
<div style="position:absolute;left:5.00px;top:581.25px" class="cls_004"><span class="cls_004">directly at design time.</span></div>
<div style="position:absolute;left:52.98px;top:604.50px" class="cls_007"><span class="cls_007">mc:Ignorable="d" Height="30" Width="300"</span></div>
<div style="position:absolute;left:67.97px;top:618.00px" class="cls_007"><span class="cls_007">d:DataContext="{Binding ViewModel,</span></div>
<div style="position:absolute;left:67.97px;top:631.50px" class="cls_007"><span class="cls_007">Source={StaticResource ViewModelLocator}}"</span></div>
<div style="position:absolute;left:5.00px;top:651.75px" class="cls_004"><span class="cls_004">While there is a clear benefit to this arrangement, as always, we have to weigh up whether</span></div>
<div style="position:absolute;left:5.00px;top:669.75px" class="cls_004"><span class="cls_004">the cost of any such abstractions will be worth the benefits. For some, the cost of</span></div>
<div style="position:absolute;left:5.00px;top:687.75px" class="cls_004"><span class="cls_004">extracting an interface, declaring a mock version of it to use at design time and creating a</span></div>
<div style="position:absolute;left:5.00px;top:705.75px" class="cls_004"><span class="cls_004">View Model Locator for each View Model will definitely be worth the benefit of designing</span></div>
<div style="position:absolute;left:5.00px;top:723.75px" class="cls_004"><span class="cls_004">Views that visualize their data.</span></div>
<div style="position:absolute;left:5.00px;top:741.75px" class="cls_004"><span class="cls_004">For others, it simply won't be worth it. Each time we add a level of abstraction, we have</span></div>
<div style="position:absolute;left:5.00px;top:759.75px" class="cls_004"><span class="cls_004">more work to achieve to arrive at the same end goal. We need to decide whether each</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:95438px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background121.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">abstraction is viable in our own situations and build our application frameworks accordingly.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:96240px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background122.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_008"><span class="cls_008">Summary</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">We've now investigated the benefit of having an application framework and started</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">constructing our own. We've discovered a variety of different ways to encapsulate our</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">required functionality into our framework and know which situations to use each in. After</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">exploring a number of manager classes, we have also begun to expose functionality from</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">external sources, but without being tied to them.</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">We've managed to maintain and improve the Separation of Concerns that our application</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">requires and should now be able to detach the various application components and run</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">them independently of each other. We are also able to provide our View designers with</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">mock data at design-time, while maintaining loose coupling at runtime.</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">In the next chapter, we will thoroughly examine the essential topic of data binding, one of</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">the very few requirements of the MVVM pattern. We'll comprehensively cover the wide</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">variety of binding syntax, both long and short hand notation, discover why bindings fail to</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">work at certain times and get a better understanding of how to display our data exactly the</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">way we want.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:97042px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background123.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_002"><span class="cls_002">Chapter 4. Becoming Proficient with Data</span></div>
<div style="position:absolute;left:5.00px;top:39.01px" class="cls_002"><span class="cls_002">Binding</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">In this chapter, we'll investigate the data binding syntax that is used to connect our data</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">sources to our UI controls. We'll examine how to declare Dependency Properties, along</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">with all of the various options that we have when doing that. We'll find out about the scope</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">of declared bindings and unravel the finer details of data templates. Let's start at the</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">beginning.</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">It is the data binding in the WPF that enables it to work so well with the MVVM pattern. It</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">provides the connection for two-way communication between the View and the View</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">Models components. Yet this abstraction can often lead to confusion and make tracking</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">down problems more difficult than when using traditional methods of UI to business logic</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">communication.</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">As data binding is such an important part of the MVVM pattern, we'll cover this topic</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">thoroughly, from the basics to advanced concepts. We'll ensure that we are able to fulfil any</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">binding requirements that we may receive.</span></div>
<div style="position:absolute;left:5.00px;top:309.01px" class="cls_008"><span class="cls_008">Data binding basics</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_004"><span class="cls_004">In WPF, we use the </span><span class="cls_007">Binding</span><span class="cls_004"> class to create our bindings. In general, it is fair to say that</span></div>
<div style="position:absolute;left:5.00px;top:363.75px" class="cls_004"><span class="cls_004">every binding will contain four constituent parts. The first is the binding source; typically, this</span></div>
<div style="position:absolute;left:5.00px;top:381.75px" class="cls_004"><span class="cls_004">will be one of our View Models. The second is the path to the property from the source</span></div>
<div style="position:absolute;left:5.00px;top:399.75px" class="cls_004"><span class="cls_004">object that we would like to data bind to.</span></div>
<div style="position:absolute;left:5.00px;top:417.75px" class="cls_004"><span class="cls_004">The third is the binding target; this will typically be a UI control. The fourth is the path to the</span></div>
<div style="position:absolute;left:5.00px;top:435.75px" class="cls_004"><span class="cls_004">property of the binding target that we want to bind to. Therefore, if one of our bindings do</span></div>
<div style="position:absolute;left:5.00px;top:453.75px" class="cls_004"><span class="cls_004">not work, it is most likely that one of these four things has not been set correctly.</span></div>
<div style="position:absolute;left:5.00px;top:471.75px" class="cls_004"><span class="cls_004">It is important to stress that the target property will typically be from a UI control, because</span></div>
<div style="position:absolute;left:5.00px;top:489.75px" class="cls_004"><span class="cls_004">there is a data binding rule that states that the binding target must be a Dependency</span></div>
<div style="position:absolute;left:5.00px;top:507.75px" class="cls_004"><span class="cls_004">Property. The properties of most UI controls are Dependency Properties and so, this rule</span></div>
<div style="position:absolute;left:5.00px;top:525.75px" class="cls_004"><span class="cls_004">simply enforces that data normally travels in the direction from our View Model data</span></div>
<div style="position:absolute;left:5.00px;top:543.75px" class="cls_004"><span class="cls_004">sources to the binding target UI controls.</span></div>
<div style="position:absolute;left:5.00px;top:561.75px" class="cls_004"><span class="cls_004">We'll examine the direction of data bound data traversal later in the chapter, but let's first</span></div>
<div style="position:absolute;left:5.00px;top:579.75px" class="cls_004"><span class="cls_004">focus on the syntax that is used to specify the value of the </span><span class="cls_007">Binding.Path</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:5.00px;top:597.01px" class="cls_011"><span class="cls_011">Binding path syntax</span></div>
<div style="position:absolute;left:5.00px;top:627.00px" class="cls_004"><span class="cls_004">Bindings can be declared either in longhand, defining an actual </span><span class="cls_007">Binding</span><span class="cls_004"> element in the</span></div>
<div style="position:absolute;left:5.00px;top:645.00px" class="cls_004"><span class="cls_004">XAML, or in shorthand, using the markup language that is translated to a </span><span class="cls_007">Binding</span><span class="cls_004"> element</span></div>
<div style="position:absolute;left:5.00px;top:663.00px" class="cls_004"><span class="cls_004">for us by the XAML. We'll primarily focus on the shorthand notation, as that is what we will</span></div>
<div style="position:absolute;left:5.00px;top:681.00px" class="cls_004"><span class="cls_004">predominantly use throughout the book.</span></div>
<div style="position:absolute;left:5.00px;top:699.00px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">Binding.Path</span><span class="cls_004"> property is of type </span><span class="cls_007">PropertyPath</span><span class="cls_004">. This type supports a unique syntax</span></div>
<div style="position:absolute;left:5.00px;top:717.00px" class="cls_004"><span class="cls_004">that can be expressed in XAML using an XAML markup extension. While it can be confusing</span></div>
<div style="position:absolute;left:5.00px;top:735.00px" class="cls_004"><span class="cls_004">at times, there are specific rules that we can learn to make it easier. Let's investigate.</span></div>
<div style="position:absolute;left:5.00px;top:753.00px" class="cls_004"><span class="cls_004">To start with, let's understand that the binding path is relative to the binding source and that</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:97844px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background124.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">the binding source is typically set by the </span><span class="cls_007">DataContext</span><span class="cls_004"> property, or by the path itself. In</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">order to bind to the whole binding source, we can specify our binding like this:</span></div>
<div style="position:absolute;left:52.98px;top:45.00px" class="cls_007"><span class="cls_007">{Binding Path=.}</span></div>
<div style="position:absolute;left:5.00px;top:65.25px" class="cls_004"><span class="cls_004">It can also be specified like this:</span></div>
<div style="position:absolute;left:52.98px;top:88.50px" class="cls_007"><span class="cls_007">{Binding .}</span></div>
<div style="position:absolute;left:5.00px;top:108.75px" class="cls_004"><span class="cls_004">Most simply, we can specify our binding like this:</span></div>
<div style="position:absolute;left:52.98px;top:132.00px" class="cls_007"><span class="cls_007">{Binding}</span></div>
<div style="position:absolute;left:5.00px;top:152.25px" class="cls_004"><span class="cls_004">Note that explicitly declaring the </span><span class="cls_007">Path</span><span class="cls_004"> property name in this syntax is optional, when the</span></div>
<div style="position:absolute;left:5.00px;top:170.25px" class="cls_004"><span class="cls_004">path value is declared first. The three preceding examples are all equal. We will omit the</span></div>
<div style="position:absolute;left:5.00px;top:188.25px" class="cls_007"><span class="cls_007">Path</span><span class="cls_004"> property declaration in the bindings in this book for brevity. Let's now see the</span></div>
<div style="position:absolute;left:5.00px;top:206.25px" class="cls_004"><span class="cls_004">remaining property path syntax mini-language.</span></div>
<div style="position:absolute;left:5.00px;top:224.25px" class="cls_004"><span class="cls_004">To data bind to most property paths, we use the same notation as we use in code. For</span></div>
<div style="position:absolute;left:5.00px;top:242.25px" class="cls_004"><span class="cls_004">example, when binding directly to the property of a data bound object, we just use the</span></div>
<div style="position:absolute;left:5.00px;top:260.25px" class="cls_004"><span class="cls_004">property name.</span></div>
<div style="position:absolute;left:52.98px;top:283.50px" class="cls_007"><span class="cls_007">{Binding PropertyName}</span></div>
<div style="position:absolute;left:5.00px;top:303.75px" class="cls_004"><span class="cls_004">To data bind to the property of an object that is directly referenced by a property of our</span></div>
<div style="position:absolute;left:5.00px;top:321.75px" class="cls_004"><span class="cls_004">binding source, we again use the same syntax that we do in code. This is known as</span></div>
<div style="position:absolute;left:5.00px;top:339.75px" class="cls_005"><span class="cls_005">indirect property targeting</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:52.98px;top:363.75px" class="cls_007"><span class="cls_007">{Binding PropertyName.AnotherPropertyName}</span></div>
<div style="position:absolute;left:5.00px;top:384.00px" class="cls_004"><span class="cls_004">Similarly, when data binding to an item in a collection, or a property of a collection item, we</span></div>
<div style="position:absolute;left:5.00px;top:402.00px" class="cls_004"><span class="cls_004">use the indexing notation from code. For example, this is how we access a property from</span></div>
<div style="position:absolute;left:5.00px;top:420.00px" class="cls_004"><span class="cls_004">the first item in our data bound binding source.</span></div>
<div style="position:absolute;left:52.98px;top:443.25px" class="cls_007"><span class="cls_007">{Binding [0].PropertyName}</span></div>
<div style="position:absolute;left:5.00px;top:463.50px" class="cls_004"><span class="cls_004">Of course, if we want to access the second item, we use a key of </span><span class="cls_007">1</span><span class="cls_004"> and use a key value of</span></div>
<div style="position:absolute;left:5.00px;top:481.50px" class="cls_007"><span class="cls_007">2</span><span class="cls_004"> if we want the third item and so on. Likewise, to indirectly target a property of a collection</span></div>
<div style="position:absolute;left:5.00px;top:499.50px" class="cls_004"><span class="cls_004">item, where the collection is a property of our binding source, we use the following syntax.:</span></div>
<div style="position:absolute;left:52.98px;top:522.75px" class="cls_007"><span class="cls_007">{Binding CollectionPropertyName[0].PropertyName}</span></div>
<div style="position:absolute;left:5.00px;top:543.00px" class="cls_004"><span class="cls_004">As you can see, we are freely able to combine these various syntactical options to</span></div>
<div style="position:absolute;left:5.00px;top:561.00px" class="cls_004"><span class="cls_004">generate more complex binding paths. Multi-dimensional collections are also accessed in</span></div>
<div style="position:absolute;left:5.00px;top:579.00px" class="cls_004"><span class="cls_004">the same way as we refer to them in code.</span></div>
<div style="position:absolute;left:52.98px;top:602.25px" class="cls_007"><span class="cls_007">{Binding CollectionPropertyName[0, 0].PropertyName}</span></div>
<div style="position:absolute;left:52.98px;top:615.75px" class="cls_007"><span class="cls_007">{Binding CollectionPropertyName[0, 0, 0].PropertyName}</span></div>
<div style="position:absolute;left:5.00px;top:649.50px" class="cls_004"><span class="cls_004">While discussing data binding to collections, note that there is a special forward slash (</span><span class="cls_007">/</span><span class="cls_004">)</span></div>
<div style="position:absolute;left:5.00px;top:667.50px" class="cls_004"><span class="cls_004">syntax that we can use to access the selected item at any time.</span></div>
<div style="position:absolute;left:52.98px;top:690.75px" class="cls_007"><span class="cls_007">{Binding CollectionPropertyName/PropertyName}</span></div>
<div style="position:absolute;left:5.00px;top:711.00px" class="cls_004"><span class="cls_004">This particular example would bind to the </span><span class="cls_007">PropertyName</span><span class="cls_004"> property of the current item of the</span></div>
<div style="position:absolute;left:5.00px;top:729.00px" class="cls_004"><span class="cls_004">collection specified by the </span><span class="cls_007">CollectionPropertyName</span><span class="cls_004"> property. Let's take a quick look at a</span></div>
<div style="position:absolute;left:5.00px;top:747.00px" class="cls_004"><span class="cls_004">more practical example:</span></div>
<div style="position:absolute;left:52.98px;top:770.25px" class="cls_007"><span class="cls_007"><StackPanel></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:98646px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background125.jpg" width=612 height=792></div>
<div style="position:absolute;left:67.97px;top:3.00px" class="cls_007"><span class="cls_007"><ListBox ItemsSource="{Binding Users}"</span></div>
<div style="position:absolute;left:82.97px;top:16.50px" class="cls_007"><span class="cls_007">IsSynchronizedWithCurrentItem="True" /></span></div>
<div style="position:absolute;left:67.97px;top:30.00px" class="cls_007"><span class="cls_007"><TextBlock Text="Selected User's Name:" /></span></div>
<div style="position:absolute;left:67.97px;top:43.50px" class="cls_007"><span class="cls_007"><TextBlock Text="{Binding Users/Name}" /></span></div>
<div style="position:absolute;left:52.98px;top:57.00px" class="cls_007"><span class="cls_007"></StackPanel></span></div>
<div style="position:absolute;left:5.00px;top:77.25px" class="cls_004"><span class="cls_004">In this basic example using our </span><span class="cls_007">UsersViewModel</span><span class="cls_004">, we data bind the </span><span class="cls_007">Users</span><span class="cls_004"> collection to a</span></div>
<div style="position:absolute;left:5.00px;top:95.25px" class="cls_004"><span class="cls_004">listbox. Underneath, we output the value of the </span><span class="cls_007">Name</span><span class="cls_004"> property from the currently selected</span></div>
<div style="position:absolute;left:5.00px;top:113.25px" class="cls_004"><span class="cls_004">item. Note the setting of the </span><span class="cls_007">IsSynchronizedWithCurrentItem</span><span class="cls_004"> property, as without it, this</span></div>
<div style="position:absolute;left:5.00px;top:131.25px" class="cls_004"><span class="cls_004">forward slash binding would not work correctly.</span></div>
<div style="position:absolute;left:5.00px;top:149.25px" class="cls_004"><span class="cls_004">Try removing the </span><span class="cls_007">IsSynchronizedWithCurrentItem</span><span class="cls_004"> property from the example and running</span></div>
<div style="position:absolute;left:5.00px;top:167.25px" class="cls_004"><span class="cls_004">the application again and you will see that the current user's name will be output initially, but</span></div>
<div style="position:absolute;left:5.00px;top:185.25px" class="cls_004"><span class="cls_004">not updated after changes to the selected item.</span></div>
<div style="position:absolute;left:5.00px;top:203.25px" class="cls_004"><span class="cls_004">Setting this property to </span><span class="cls_007">True</span><span class="cls_004"> will ensure that the </span><span class="cls_007">ItemCollection.CurrentItem</span><span class="cls_004"> property</span></div>
<div style="position:absolute;left:5.00px;top:221.25px" class="cls_004"><span class="cls_004">from the </span><span class="cls_007">ListBox.Items</span><span class="cls_004"> collection is updated each time the selection changes. Note that we</span></div>
<div style="position:absolute;left:5.00px;top:239.25px" class="cls_004"><span class="cls_004">could also achieve this same output using the </span><span class="cls_007">ListBox.SelectedItem</span><span class="cls_004"> property instead of</span></div>
<div style="position:absolute;left:5.00px;top:257.25px" class="cls_004"><span class="cls_004">this forward slash notation.</span></div>
<div style="position:absolute;left:52.98px;top:280.50px" class="cls_007"><span class="cls_007"><StackPanel></span></div>
<div style="position:absolute;left:67.97px;top:294.00px" class="cls_007"><span class="cls_007"><ListBox Name="ListBox" ItemsSource="{Binding Users}"</span></div>
<div style="position:absolute;left:82.97px;top:307.50px" class="cls_007"><span class="cls_007">IsSynchronizedWithCurrentItem="True" /></span></div>
<div style="position:absolute;left:67.97px;top:321.00px" class="cls_007"><span class="cls_007"><TextBlock Text="Selected User's Name:" /></span></div>
<div style="position:absolute;left:67.97px;top:334.50px" class="cls_007"><span class="cls_007"><TextBlock Text="{Binding SelectedItem.Name,</span></div>
<div style="position:absolute;left:52.98px;top:348.00px" class="cls_007"><span class="cls_007">ElementName=ListBox}" /></span></div>
<div style="position:absolute;left:52.98px;top:361.50px" class="cls_007"><span class="cls_007"></StackPanel></span></div>
<div style="position:absolute;left:5.00px;top:381.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">IsSynchronizedWithCurrentItem</span><span class="cls_004"> property is now not needed to update the selected</span></div>
<div style="position:absolute;left:5.00px;top:399.75px" class="cls_004"><span class="cls_004">user's name in the </span><span class="cls_007">TextBlock</span><span class="cls_004">, because the </span><span class="cls_007">SelectedItem</span><span class="cls_004"> property will take care of that.</span></div>
<div style="position:absolute;left:5.00px;top:417.75px" class="cls_004"><span class="cls_004">However, setting it to </span><span class="cls_007">True</span><span class="cls_004"> in this case will ensure that the first item in the </span><span class="cls_007">ListBox</span><span class="cls_004"> is</span></div>
<div style="position:absolute;left:5.00px;top:435.75px" class="cls_004"><span class="cls_004">selected and that the </span><span class="cls_007">TextBlock</span><span class="cls_004"> will initially output the name of that item's user. Let's</span></div>
<div style="position:absolute;left:5.00px;top:453.75px" class="cls_004"><span class="cls_004">continue looking at the forward slash notation.</span></div>
<div style="position:absolute;left:5.00px;top:471.75px" class="cls_004"><span class="cls_004">If you are trying to data bind to a property of an item in a collection where, the collection is</span></div>
<div style="position:absolute;left:5.00px;top:489.75px" class="cls_004"><span class="cls_004">itself an item of a parent collection, we can use the forward slash notation multiple times in</span></div>
<div style="position:absolute;left:5.00px;top:507.75px" class="cls_004"><span class="cls_004">a single binding path.</span></div>
<div style="position:absolute;left:52.98px;top:531.00px" class="cls_007"><span class="cls_007">{Binding</span></div>
<div style="position:absolute;left:52.98px;top:544.50px" class="cls_007"><span class="cls_007">CollectionPropertyName/InnerCollectionPropertyName/PropertyName}</span></div>
<div style="position:absolute;left:5.00px;top:564.75px" class="cls_004"><span class="cls_004">To clarify, this path would bind to the </span><span class="cls_007">PropertyName</span><span class="cls_004"> property of the selected item of the</span></div>
<div style="position:absolute;left:5.00px;top:582.75px" class="cls_004"><span class="cls_004">collection specified by the </span><span class="cls_007">InnerCollectionPropertyName</span><span class="cls_004"> property, which itself is the</span></div>
<div style="position:absolute;left:5.00px;top:600.75px" class="cls_004"><span class="cls_004">selected item of the collection specified by the </span><span class="cls_007">CollectionPropertyName</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:5.00px;top:618.75px" class="cls_004"><span class="cls_004">Let's move on from collections now, to Attached Properties. In order to data bind to an</span></div>
<div style="position:absolute;left:5.00px;top:636.75px" class="cls_004"><span class="cls_004">Attached Property, we need to use a slightly different syntax from that used in code; we</span></div>
<div style="position:absolute;left:5.00px;top:654.75px" class="cls_004"><span class="cls_004">need to enclose the property name in parenthesis, along with the class name.</span></div>
<div style="position:absolute;left:52.98px;top:678.00px" class="cls_007"><span class="cls_007">{Binding (ClassName.PropertyName)}</span></div>
<div style="position:absolute;left:5.00px;top:698.25px" class="cls_004"><span class="cls_004">Note that when the Attached Property is a custom-declared property, we must include the</span></div>
<div style="position:absolute;left:5.00px;top:716.25px" class="cls_004"><span class="cls_004">XML namespace prefix inside the parenthesis with its separating colon.</span></div>
<div style="position:absolute;left:52.98px;top:739.50px" class="cls_007"><span class="cls_007">{Binding (XmlNamespacePrefix:ClassName.PropertyName)}</span></div>
<div style="position:absolute;left:5.00px;top:759.75px" class="cls_004"><span class="cls_004">Typically, when binding to Attached Properties, we also need to specify the binding target</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:99448px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background126.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">as well as the target property. The binding target will generally either be the object that the</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">binding is set on, or another UI element, so we tend to see the </span><span class="cls_007">RelativeSource</span><span class="cls_004"> or</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_007"><span class="cls_007">ElementName</span><span class="cls_004"> properties being used in these situations.</span></div>
<div style="position:absolute;left:52.98px;top:63.00px" class="cls_007"><span class="cls_007">{Binding Path=(Attached:TextBoxProperties.Label),</span></div>
<div style="position:absolute;left:67.97px;top:76.50px" class="cls_007"><span class="cls_007">RelativeSource={RelativeSource AncestorType={x:Type TextBox}}}</span></div>
<div style="position:absolute;left:5.00px;top:96.75px" class="cls_004"><span class="cls_004">We'll see an extended version of this example later in the book, but in short, it binds to the</span></div>
<div style="position:absolute;left:5.00px;top:114.75px" class="cls_007"><span class="cls_007">TextBoxProperties.Label</span><span class="cls_004"> Attached Property of the parent control of type </span><span class="cls_007">TextBox</span><span class="cls_004">. It is</span></div>
<div style="position:absolute;left:5.00px;top:132.75px" class="cls_004"><span class="cls_004">called from within a </span><span class="cls_007">ControlTemplate</span><span class="cls_004"> and so, the parent textbox is the templated parent of</span></div>
<div style="position:absolute;left:5.00px;top:150.75px" class="cls_004"><span class="cls_004">the control that is being data bound.</span></div>
<div style="position:absolute;left:5.00px;top:168.00px" class="cls_013"><span class="cls_013">Escaping invalid characters</span></div>
<div style="position:absolute;left:5.00px;top:193.50px" class="cls_004"><span class="cls_004">When using the </span><span class="cls_007">PropertyPath</span><span class="cls_004"> syntax mini-language, there may be the odd occasion when</span></div>
<div style="position:absolute;left:5.00px;top:211.50px" class="cls_004"><span class="cls_004">we need to escape certain characters that are used in the syntax. In general, the backslash</span></div>
<div style="position:absolute;left:5.00px;top:229.50px" class="cls_004"><span class="cls_004">(</span><span class="cls_007">\</span><span class="cls_004">) is used as the escape character and the only characters that we need to escape are as</span></div>
<div style="position:absolute;left:5.00px;top:247.50px" class="cls_004"><span class="cls_004">follows.</span></div>
<div style="position:absolute;left:5.00px;top:265.50px" class="cls_004"><span class="cls_004">The most common character that we may need to escape in our bind paths is the closing</span></div>
<div style="position:absolute;left:5.00px;top:283.50px" class="cls_004"><span class="cls_004">curly bracket (</span><span class="cls_007">}</span><span class="cls_004">), which signals the end of a markup section. Also, if you need to use an</span></div>
<div style="position:absolute;left:5.00px;top:301.50px" class="cls_004"><span class="cls_004">actual backslash in your binding path, then you must escape it by preceding it with another</span></div>
<div style="position:absolute;left:5.00px;top:319.50px" class="cls_004"><span class="cls_004">backslash.</span></div>
<div style="position:absolute;left:5.00px;top:337.50px" class="cls_004"><span class="cls_004">The only two other characters that we need to escape are the equals sign (</span><span class="cls_007">=</span><span class="cls_004">) and the</span></div>
<div style="position:absolute;left:5.00px;top:355.50px" class="cls_004"><span class="cls_004">comma character (</span><span class="cls_007">,</span><span class="cls_004">), which are both used to define binding paths. All other characters that</span></div>
<div style="position:absolute;left:5.00px;top:373.50px" class="cls_004"><span class="cls_004">we are likely to use in a binding path are deemed to be valid.</span></div>
<div style="position:absolute;left:5.00px;top:391.50px" class="cls_004"><span class="cls_004">Note that there is a special character to use if we need to escape a character when inside</span></div>
<div style="position:absolute;left:5.00px;top:409.50px" class="cls_004"><span class="cls_004">an indexer binding expression. In these cases, instead of using the backslash character, we</span></div>
<div style="position:absolute;left:5.00px;top:427.50px" class="cls_004"><span class="cls_004">need to use the caret character (</span><span class="cls_007">^</span><span class="cls_004">) as the escape character.</span></div>
<div style="position:absolute;left:5.00px;top:445.50px" class="cls_004"><span class="cls_004">Also note that when explicitly declaring bindings in XAML, we need to escape the</span></div>
<div style="position:absolute;left:5.00px;top:463.50px" class="cls_004"><span class="cls_004">ampersand (</span><span class="cls_007">&</span><span class="cls_004">) and the greater than sign (</span><span class="cls_007">></span><span class="cls_004">) by replacing them with their XML Entity forms.</span></div>
<div style="position:absolute;left:5.00px;top:481.50px" class="cls_004"><span class="cls_004">If you need to use these characters, then replace the ampersand with </span><span class="cls_007">&</span><span class="cls_004"> and replace</span></div>
<div style="position:absolute;left:5.00px;top:499.50px" class="cls_004"><span class="cls_004">the greater than sign with </span><span class="cls_007">></span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:516.76px" class="cls_011"><span class="cls_011">Exploring the Binding class</span></div>
<div style="position:absolute;left:5.00px;top:546.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">Binding</span><span class="cls_004"> class has more properties than we have space to discuss here, but we'll cover</span></div>
<div style="position:absolute;left:5.00px;top:564.75px" class="cls_004"><span class="cls_004">the most important ones in detail shortly, and briefly look at other notable properties</span></div>
<div style="position:absolute;left:5.00px;top:582.75px" class="cls_004"><span class="cls_004">momentarily. The </span><span class="cls_007">Binding</span><span class="cls_004"> class is the top-level class in each binding, but internally it uses a</span></div>
<div style="position:absolute;left:5.00px;top:600.75px" class="cls_004"><span class="cls_004">lower-level class that maintains the connection between the binding source and binding</span></div>
<div style="position:absolute;left:5.00px;top:618.75px" class="cls_004"><span class="cls_004">target.</span></div>
<div style="position:absolute;left:5.00px;top:636.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">BindingExpression</span><span class="cls_004"> class is that underlying object. When using MVVM, developers do</span></div>
<div style="position:absolute;left:5.00px;top:654.75px" class="cls_004"><span class="cls_004">not typically access this inner class, as we tend to keep our functionality in our View</span></div>
<div style="position:absolute;left:5.00px;top:672.75px" class="cls_004"><span class="cls_004">Models. However, if we are writing custom controls, then it can be useful to be aware of it.</span></div>
<div style="position:absolute;left:5.00px;top:690.75px" class="cls_004"><span class="cls_004">It can be used to programmatically update the associated binding source in certain</span></div>
<div style="position:absolute;left:5.00px;top:708.75px" class="cls_004"><span class="cls_004">circumstances and we'll find out about that later in the chapter. For now, let's focus on what</span></div>
<div style="position:absolute;left:5.00px;top:726.75px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">Binding</span><span class="cls_004"> class can do for us.</span></div>
<div style="position:absolute;left:5.00px;top:744.75px" class="cls_004"><span class="cls_004">In .NET 4.5, a great new property was added to the </span><span class="cls_007">Binding</span><span class="cls_004"> class. The </span><span class="cls_007">Delay</span><span class="cls_004"> property</span></div>
<div style="position:absolute;left:5.00px;top:762.75px" class="cls_004"><span class="cls_004">enables us to specify an amount of time in milliseconds with which to delay the update of</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:100250px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background127.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">the binding source after a change has been made to the binding target property value.</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">This is really useful if we are performing some heavy computational validation or other</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">processing dependent upon the user's input in a textbox for example. To clarify this</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">functionality further, this delay is actually restarted each time the data bound property value</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">changes, or each key press in our example. It is typically used to update the binding source</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">in chunks, each time the user pauses, or completes typing, somewhat like buffering.</span></div>
<div style="position:absolute;left:52.98px;top:117.00px" class="cls_007"><span class="cls_007"><TextBox Text="{Binding Description,</span></div>
<div style="position:absolute;left:67.97px;top:130.50px" class="cls_007"><span class="cls_007">UpdateSourceTrigger=PropertyChanged, Delay=400}" /></span></div>
<div style="position:absolute;left:5.00px;top:150.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">FallbackValue</span><span class="cls_004"> property is another useful property when it comes to performance. In</span></div>
<div style="position:absolute;left:5.00px;top:168.75px" class="cls_004"><span class="cls_004">order to return a value from each binding, the WPF Framework does up to four things. The</span></div>
<div style="position:absolute;left:5.00px;top:186.75px" class="cls_004"><span class="cls_004">first is to simply validate the target property type with the data bound value. If successful, it</span></div>
<div style="position:absolute;left:5.00px;top:204.75px" class="cls_004"><span class="cls_004">will then try to resolve the binding path.</span></div>
<div style="position:absolute;left:5.00px;top:222.75px" class="cls_004"><span class="cls_004">Most of the time, this will work, but if not, it will then attempt to find a converter to return</span></div>
<div style="position:absolute;left:5.00px;top:240.75px" class="cls_004"><span class="cls_004">the value. If it can't find one, or it returns the </span><span class="cls_007">DependencyProperty.UnsetValue</span><span class="cls_004"> value, it will</span></div>
<div style="position:absolute;left:5.00px;top:258.75px" class="cls_004"><span class="cls_004">then look to see if the </span><span class="cls_007">FallbackValue</span><span class="cls_004"> property has a value to provide it with. If there is no</span></div>
<div style="position:absolute;left:5.00px;top:276.75px" class="cls_004"><span class="cls_004">fallback value, then a lookup is required to find the default value of the target Dependency</span></div>
<div style="position:absolute;left:5.00px;top:294.75px" class="cls_004"><span class="cls_004">Property.</span></div>
<div style="position:absolute;left:5.00px;top:312.75px" class="cls_004"><span class="cls_004">By setting the </span><span class="cls_007">FallbackValue</span><span class="cls_004"> property, we can do two things to improve performance,</span></div>
<div style="position:absolute;left:5.00px;top:330.75px" class="cls_004"><span class="cls_004">albeit in a slight way. The first is that, it will stop the WPF Framework from performing the</span></div>
<div style="position:absolute;left:5.00px;top:348.75px" class="cls_004"><span class="cls_004">lookup of the default value of the target Dependency Property. The second is that it will</span></div>
<div style="position:absolute;left:5.00px;top:366.75px" class="cls_004"><span class="cls_004">prevent trace statements from being fed to the </span><span class="cls_005">Output</span><span class="cls_004"> window in Visual Studio and to any</span></div>
<div style="position:absolute;left:5.00px;top:385.50px" class="cls_004"><span class="cls_004">other trace outputs that have been setup.</span></div>
<div style="position:absolute;left:5.00px;top:403.50px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">TargetNullValue</span><span class="cls_004"> property is similar to the </span><span class="cls_007">FallbackValue</span><span class="cls_004"> property in that it enables us</span></div>
<div style="position:absolute;left:5.00px;top:421.50px" class="cls_004"><span class="cls_004">to provide some output when there is no data bound value from the binding source. The</span></div>
<div style="position:absolute;left:5.00px;top:439.50px" class="cls_004"><span class="cls_004">difference is that the </span><span class="cls_007">FallbackValue</span><span class="cls_004"> property value is output when a data bound value</span></div>
<div style="position:absolute;left:5.00px;top:457.50px" class="cls_004"><span class="cls_004">cannot be resolved, while the </span><span class="cls_007">TargetNullValue</span><span class="cls_004"> property value is used when the</span></div>
<div style="position:absolute;left:5.00px;top:475.50px" class="cls_004"><span class="cls_004">successfully resolved data bound value is null.</span></div>
<div style="position:absolute;left:5.00px;top:493.50px" class="cls_004"><span class="cls_004">We can use this functionality to display a more humanized value than 'null', or even to</span></div>
<div style="position:absolute;left:5.00px;top:511.50px" class="cls_004"><span class="cls_004">provide a default message in our textbox controls for example. To do this, we could set our</span></div>
<div style="position:absolute;left:5.00px;top:529.50px" class="cls_004"><span class="cls_004">data bound string properties to null and set a suitable value to the </span><span class="cls_007">TargetNullValue</span></div>
<div style="position:absolute;left:5.00px;top:547.50px" class="cls_004"><span class="cls_004">property.</span></div>
<div style="position:absolute;left:52.98px;top:570.75px" class="cls_007"><span class="cls_007"><TextBox Text="{Binding Name, TargetNullValue='Please enter your</span></div>
<div style="position:absolute;left:52.98px;top:584.25px" class="cls_007"><span class="cls_007">name'}" /></span></div>
<div style="position:absolute;left:5.00px;top:604.50px" class="cls_004"><span class="cls_004">Of course, this 'message' will actually appear in the textbox, so it's not an ideal way of</span></div>
<div style="position:absolute;left:5.00px;top:622.50px" class="cls_004"><span class="cls_004">providing this functionality. We'll see a better example of this later in the book, but now let's</span></div>
<div style="position:absolute;left:5.00px;top:640.50px" class="cls_004"><span class="cls_004">continue our exploration of the </span><span class="cls_007">Binding</span><span class="cls_004"> class.</span></div>
<div style="position:absolute;left:5.00px;top:658.50px" class="cls_004"><span class="cls_004">If you have any properties in your View Model that access their data asynchronously, or if</span></div>
<div style="position:absolute;left:5.00px;top:676.50px" class="cls_004"><span class="cls_004">they are calculated by a heavy computational process, then we need to set the </span><span class="cls_007">IsAsync</span></div>
<div style="position:absolute;left:5.00px;top:694.50px" class="cls_004"><span class="cls_004">method to </span><span class="cls_007">True</span><span class="cls_004"> on the binding.</span></div>
<div style="position:absolute;left:52.98px;top:717.75px" class="cls_007"><span class="cls_007"><Image Source="{Binding InternetSource, IsAsync=True,</span></div>
<div style="position:absolute;left:52.98px;top:744.75px" class="cls_007"><span class="cls_007">FallbackValue='pack://application:,,,/CompanyName.ApplicationName;</span></div>
<div style="position:absolute;left:67.97px;top:758.25px" class="cls_007"><span class="cls_007">component/Images/Default.png'}" /></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:101052px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background128.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">This stops the UI from being blocked while waiting for the data bound property to be</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">calculated, or otherwise resolved. Until the binding source is resolved, the fallback value is</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">used if set, or the default value will be used if not. In this example, we are providing a</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">default image to be displayed until the actual image is downloaded from the internet and the</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">binding source is resolved.</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">Another useful property of the </span><span class="cls_007">Binding</span><span class="cls_004"> class is the </span><span class="cls_007">StringFormat</span><span class="cls_004"> property. As the name</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">hints, this uses the </span><span class="cls_007">string.Format</span><span class="cls_004"> method internally to format our data bound text output.</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">There are however, a few caveats to using this functionality. The first is that we can</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">obviously only use a single format item, that represents the single data bound value in a</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">normal binding. We'll find out how to use multiple values later in the chapter.</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">Secondly, we need to declare our format carefully, as curly brackets are used by the</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">markup extensions and we cannot use the double quote characters (</span><span class="cls_007">"</span><span class="cls_004">), as the binding is</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">already declared within double quotes. One solution is to use single quotes.</span></div>
<div style="position:absolute;left:52.98px;top:243.00px" class="cls_007"><span class="cls_007"><TextBlock Text="{Binding Price, StringFormat='{0:C2}'}" /></span></div>
<div style="position:absolute;left:5.00px;top:263.25px" class="cls_004"><span class="cls_004">Another option is to escape the format by using a pair of curly brackets before it.</span></div>
<div style="position:absolute;left:52.98px;top:286.50px" class="cls_007"><span class="cls_007"><TextBlock Text="{Binding Price, StringFormat={}{0:C2}}" /></span></div>
<div style="position:absolute;left:5.00px;top:306.75px" class="cls_004"><span class="cls_004">Most of the useful binding properties have now been discussed here, but it should be noted</span></div>
<div style="position:absolute;left:5.00px;top:324.75px" class="cls_004"><span class="cls_004">that there are a number of properties in the </span><span class="cls_007">Binding</span><span class="cls_004"> class that are not typically used when</span></div>
<div style="position:absolute;left:5.00px;top:342.75px" class="cls_004"><span class="cls_004">building a WPF application with MVVM. This is because they involve event handlers and we</span></div>
<div style="position:absolute;left:5.00px;top:360.75px" class="cls_004"><span class="cls_004">do not normally implement event handlers when using MVVM.</span></div>
<div style="position:absolute;left:5.00px;top:378.75px" class="cls_004"><span class="cls_004">For example, the three </span><span class="cls_007">NotifyOnSourceUpdated</span><span class="cls_004">, </span><span class="cls_007">NotifyOnTargetUpdated</span><span class="cls_004">, and</span></div>
<div style="position:absolute;left:5.00px;top:396.75px" class="cls_007"><span class="cls_007">NotifyOnValidationError</span><span class="cls_004"> properties relate to the raising of the </span><span class="cls_007">Binding.SourceUpdated</span><span class="cls_004">,</span></div>
<div style="position:absolute;left:5.00px;top:414.75px" class="cls_007"><span class="cls_007">Binding.TargetUpdated</span><span class="cls_004"> and </span><span class="cls_007">Validation.Error</span><span class="cls_004"> Attached Events.</span></div>
<div style="position:absolute;left:5.00px;top:432.75px" class="cls_004"><span class="cls_004">Likewise, the three </span><span class="cls_007">ValidatesOnDataErrors</span><span class="cls_004">, </span><span class="cls_007">ValidatesOnExceptions</span><span class="cls_004">,</span></div>
<div style="position:absolute;left:5.00px;top:450.75px" class="cls_007"><span class="cls_007">ValidatesOnNotifyDataErrors</span><span class="cls_004"> and </span><span class="cls_007">ValidationRules</span><span class="cls_004"> properties all relate to the use of the</span></div>
<div style="position:absolute;left:5.00px;top:468.75px" class="cls_007"><span class="cls_007">ValidationRule</span><span class="cls_004"> class. This is a very UI-related way of validating, but this puts our business</span></div>
<div style="position:absolute;left:5.00px;top:486.75px" class="cls_004"><span class="cls_004">logic right into our Views component.</span></div>
<div style="position:absolute;left:5.00px;top:504.75px" class="cls_004"><span class="cls_004">When using MVVM, we want to avoid this blending of components. We therefore tend to</span></div>
<div style="position:absolute;left:5.00px;top:522.75px" class="cls_004"><span class="cls_004">work with data elements rather than UI elements and so, we perform these kind of duties in</span></div>
<div style="position:absolute;left:5.00px;top:540.75px" class="cls_004"><span class="cls_004">our Data Model and/or View Model classes instead. We'll see this in </span><span class="cls_015">Chapter 8</span><span class="cls_004">,</span></div>
<div style="position:absolute;left:5.00px;top:558.75px" class="cls_006"><span class="cls_006">Implementing Responsive Data Validation</span><span class="cls_004"> later in the book, but now let's take a deeper</span></div>
<div style="position:absolute;left:5.00px;top:577.50px" class="cls_004"><span class="cls_004">look at the most important properties of the </span><span class="cls_007">Binding</span><span class="cls_004"> class.</span></div>
<div style="position:absolute;left:5.00px;top:594.75px" class="cls_013"><span class="cls_013">Directing data bound traffic</span></div>
<div style="position:absolute;left:5.00px;top:620.25px" class="cls_004"><span class="cls_004">The direction of data traversal in each binding is specified by the </span><span class="cls_007">Binding.Mode</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:5.00px;top:638.25px" class="cls_004"><span class="cls_004">There are four distinct directional instances declared in the </span><span class="cls_007">BindingMode</span><span class="cls_004"> enumeration, plus</span></div>
<div style="position:absolute;left:5.00px;top:656.25px" class="cls_004"><span class="cls_004">an additional value. Let's first take a look at the directional values and what they represent.</span></div>
<div style="position:absolute;left:5.00px;top:674.25px" class="cls_004"><span class="cls_004">The first and most common value reflects the most common situation, where data flows</span></div>
<div style="position:absolute;left:5.00px;top:692.25px" class="cls_004"><span class="cls_004">from the binding source, say one of our View Models, to the binding target represented by</span></div>
<div style="position:absolute;left:5.00px;top:710.25px" class="cls_004"><span class="cls_004">a UI control. This binding mode is called </span><span class="cls_005">One-Way</span><span class="cls_004"> and is specified by the </span><span class="cls_007">OneWay</span></div>
<div style="position:absolute;left:5.00px;top:729.00px" class="cls_004"><span class="cls_004">enumeration instance. This mode is used primarily for display only, or read-only purposes</span></div>
<div style="position:absolute;left:5.00px;top:747.00px" class="cls_004"><span class="cls_004">and situations where the data bound values cannot be altered in the UI.</span></div>
<div style="position:absolute;left:5.00px;top:765.00px" class="cls_004"><span class="cls_004">The next most common direction of travel is represented by the </span><span class="cls_007">TwoWay</span><span class="cls_004"> enumeration</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:101854px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background129.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">instance and signifies that data is free to travel both from our View Models to the UI</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">controls and also in the opposite direction. This is the most commonly used mode when</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">data binding to form controls, when we want the users' changes to be reflected in our View</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">Models.</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">The third directional enumeration instance is the </span><span class="cls_007">OneWayToSource</span><span class="cls_004"> instance and is the</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">opposite to the </span><span class="cls_007">OneWay</span><span class="cls_004"> instance. That is, it specifies that data can only travel from the</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">binding target, represented by a UI control, to the binding source, for example, one of our</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">View Models. This mode is also useful for capturing user inputted date, when we don't need</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">to alter the data bound values.</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">The final directional instance is similar to the </span><span class="cls_007">OneWay</span><span class="cls_004"> instance, except that it only works</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">once, and is represented by the </span><span class="cls_007">OneTime</span><span class="cls_004"> instance. While this mode will indeed only work</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">one time upon instantiation of its containing control, it will actually update its value each time</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">DataContext</span><span class="cls_004"> property of the relevant binding is set.</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">The final instance is named </span><span class="cls_007">Default</span><span class="cls_004"> and as the name hints, is the default value of the</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_007"><span class="cls_007">Binding.Mode</span><span class="cls_004"> enumeration. It directs the binding to use the binding mode that was declared</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">from the specified target property. When each Dependency Property is declared, we can</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">specify whether a One or </span><span class="cls_005">Two-Way</span><span class="cls_004"> binding mode should be used by default. If this is not</span></div>
<div style="position:absolute;left:5.00px;top:310.50px" class="cls_004"><span class="cls_004">specifically declared, then the property will be assigned a One-Way mode. We'll see this</span></div>
<div style="position:absolute;left:5.00px;top:328.50px" class="cls_004"><span class="cls_004">explained in more detail later in this chapter.</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_013"><span class="cls_013">Binding to different sources</span></div>
<div style="position:absolute;left:5.00px;top:371.25px" class="cls_004"><span class="cls_004">We generally set the binding source using the </span><span class="cls_007">FrameworkElement.DataContext</span><span class="cls_004"> property. All</span></div>
<div style="position:absolute;left:5.00px;top:389.25px" class="cls_004"><span class="cls_004">UI controls extend the </span><span class="cls_007">FrameworkElement</span><span class="cls_004"> class, so we can set our binding sources on any</span></div>
<div style="position:absolute;left:5.00px;top:407.25px" class="cls_004"><span class="cls_004">of them. This must be set for a binding to work, although it can be specified in the </span><span class="cls_007">Path</span></div>
<div style="position:absolute;left:5.00px;top:425.25px" class="cls_004"><span class="cls_004">property, or inherited from ancestor controls, so it does not have to be explicitly set. Take a</span></div>
<div style="position:absolute;left:5.00px;top:443.25px" class="cls_004"><span class="cls_004">look at this simple example that assumes that a suitable binding source has been correctly</span></div>
<div style="position:absolute;left:5.00px;top:461.25px" class="cls_004"><span class="cls_004">set on the parent control:</span></div>
<div style="position:absolute;left:52.98px;top:484.50px" class="cls_007"><span class="cls_007"><StackPanel></span></div>
<div style="position:absolute;left:67.97px;top:498.00px" class="cls_007"><span class="cls_007"><TextBlock DataContext="{Binding User}" Text="{Binding Name}" /></span></div>
<div style="position:absolute;left:67.97px;top:511.50px" class="cls_007"><span class="cls_007"><TextBlock DataContext="{Binding User}" Text="{Binding Age}" /></span></div>
<div style="position:absolute;left:52.98px;top:525.00px" class="cls_007"><span class="cls_007"></StackPanel></span></div>
<div style="position:absolute;left:5.00px;top:545.25px" class="cls_004"><span class="cls_004">Here, we set the binding source of the first </span><span class="cls_007">TextBlock</span><span class="cls_004"> to a </span><span class="cls_007">User</span><span class="cls_004"> object and the path to the</span></div>
<div style="position:absolute;left:5.00px;top:563.25px" class="cls_007"><span class="cls_007">Name</span><span class="cls_004"> property from that source. The second is set likewise, but with the binding source path</span></div>
<div style="position:absolute;left:5.00px;top:581.25px" class="cls_004"><span class="cls_004">pointing to the </span><span class="cls_007">Age</span><span class="cls_004"> property instead. Note that we have set the </span><span class="cls_007">DataContext</span><span class="cls_004"> property to a</span></div>
<div style="position:absolute;left:5.00px;top:599.25px" class="cls_007"><span class="cls_007">User</span><span class="cls_004"> object on each </span><span class="cls_007">TextBox</span><span class="cls_004"> control individually.</span></div>
<div style="position:absolute;left:5.00px;top:617.25px" class="cls_004"><span class="cls_004">While this is perfectly valid XAML, you can imagine how tiresome it would be to do this on</span></div>
<div style="position:absolute;left:5.00px;top:635.25px" class="cls_004"><span class="cls_004">every control that we want to data bind to in a large form. As such, we tend to take</span></div>
<div style="position:absolute;left:5.00px;top:653.25px" class="cls_004"><span class="cls_004">advantage of the fact that the </span><span class="cls_007">DataContext</span><span class="cls_004"> property can inherit its value from any of its</span></div>
<div style="position:absolute;left:5.00px;top:671.25px" class="cls_004"><span class="cls_004">ancestor controls. In this way, we can simplify this code by setting the </span><span class="cls_007">DataContext</span><span class="cls_004"> on the</span></div>
<div style="position:absolute;left:5.00px;top:689.25px" class="cls_004"><span class="cls_004">parent control instead.</span></div>
<div style="position:absolute;left:52.98px;top:712.50px" class="cls_007"><span class="cls_007"><StackPanel DataContext="{Binding User}"></span></div>
<div style="position:absolute;left:67.97px;top:726.00px" class="cls_007"><span class="cls_007"><TextBlock Text="{Binding Name}" /></span></div>
<div style="position:absolute;left:67.97px;top:739.50px" class="cls_007"><span class="cls_007"><TextBlock Text="{Binding Age}" /></span></div>
<div style="position:absolute;left:52.98px;top:753.00px" class="cls_007"><span class="cls_007"></StackPanel></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:102656px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background130.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">In fact, when developing each </span><span class="cls_007">Window</span><span class="cls_004"> or </span><span class="cls_007">UserControl</span><span class="cls_004">, it is customary to set the</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_007"><span class="cls_007">DataContext</span><span class="cls_004"> on these top-level controls, so that every contained control will have access to</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">the same binding source. This is why we create a View Model for each </span><span class="cls_007">Window</span><span class="cls_004"> or</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_007"><span class="cls_007">UserControl</span><span class="cls_004"> and specify that each View Model is responsible for providing all of the data</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">and functionality that its related View requires.</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">There are a few alternative ways of specifying a binding source, other than setting the</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_007"><span class="cls_007">DataContext</span><span class="cls_004"> property. One way is to use the </span><span class="cls_007">Source</span><span class="cls_004"> property of the binding and this</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">enables us to explicitly override the binding source that is inherited from the parent</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_007"><span class="cls_007">DataContext</span><span class="cls_004">, if one was set. Using the </span><span class="cls_007">Source</span><span class="cls_004"> property, we are also able to data bind to</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">resources, as we saw in our View Model Locator example, or static values, as shown in the</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">following snippet:</span></div>
<div style="position:absolute;left:52.98px;top:207.00px" class="cls_007"><span class="cls_007"><TextBlock Text="{Binding Source={x:Static System:DateTime.Today},</span></div>
<div style="position:absolute;left:67.97px;top:220.50px" class="cls_007"><span class="cls_007">Mode=OneTime, StringFormat='{}© {0:yyyy} CompanyName'}" /></span></div>
<div style="position:absolute;left:5.00px;top:240.75px" class="cls_004"><span class="cls_004">Another way involves the use of the </span><span class="cls_007">RelativeSource</span><span class="cls_004"> property of the binding. Using this</span></div>
<div style="position:absolute;left:5.00px;top:258.75px" class="cls_004"><span class="cls_004">incredibly useful property of type </span><span class="cls_007">RelativeSource</span><span class="cls_004">, we can specify that we want to use the</span></div>
<div style="position:absolute;left:5.00px;top:276.75px" class="cls_004"><span class="cls_004">target control, or a parent of that control as the binding source.</span></div>
<div style="position:absolute;left:5.00px;top:294.75px" class="cls_004"><span class="cls_004">It also enables us to override the binding source from the </span><span class="cls_007">DataContext</span><span class="cls_004"> and is often</span></div>
<div style="position:absolute;left:5.00px;top:312.75px" class="cls_004"><span class="cls_004">essential when trying to data bind to View Model properties from </span><span class="cls_007">DataTemplate</span><span class="cls_004"> elements.</span></div>
<div style="position:absolute;left:5.00px;top:330.75px" class="cls_004"><span class="cls_004">Let's adjust the earlier </span><span class="cls_007">DataTemplate</span><span class="cls_004"> for our </span><span class="cls_007">User</span><span class="cls_004"> Data Model to output a property from its</span></div>
<div style="position:absolute;left:5.00px;top:348.75px" class="cls_004"><span class="cls_004">normal </span><span class="cls_007">DataContext</span><span class="cls_004"> that is set by the </span><span class="cls_007">DataTemplate</span><span class="cls_004">, and one from the View Model that is</span></div>
<div style="position:absolute;left:5.00px;top:366.75px" class="cls_004"><span class="cls_004">set as the </span><span class="cls_007">DataContext</span><span class="cls_004"> of the parent control, using the </span><span class="cls_007">AncestorType</span><span class="cls_004"> property of the</span></div>
<div style="position:absolute;left:5.00px;top:384.75px" class="cls_007"><span class="cls_007">RelativeSource</span><span class="cls_004"> class.</span></div>
<div style="position:absolute;left:52.98px;top:408.00px" class="cls_007"><span class="cls_007"><DataTemplate DataType="{x:Type DataModels:User}"></span></div>
<div style="position:absolute;left:67.97px;top:421.50px" class="cls_007"><span class="cls_007"><StackPanel></span></div>
<div style="position:absolute;left:82.97px;top:435.00px" class="cls_007"><span class="cls_007"><TextBlock Text="{Binding Name}" /></span></div>
<div style="position:absolute;left:82.97px;top:448.50px" class="cls_007"><span class="cls_007"><TextBlock Text="{Binding DataContext.UserCount,</span></div>
<div style="position:absolute;left:97.96px;top:462.00px" class="cls_007"><span class="cls_007">RelativeSource={RelativeSource Mode=FindAncestor,</span></div>
<div style="position:absolute;left:97.96px;top:475.50px" class="cls_007"><span class="cls_007">AncestorType={x:Type Views:UserView}}}" /></span></div>
<div style="position:absolute;left:67.97px;top:489.00px" class="cls_007"><span class="cls_007"></StackPanel></span></div>
<div style="position:absolute;left:52.98px;top:502.50px" class="cls_007"><span class="cls_007"></DataTemplate></span></div>
<div style="position:absolute;left:5.00px;top:522.75px" class="cls_004"><span class="cls_004">Note that setting the </span><span class="cls_007">Mode</span><span class="cls_004"> property, that specifies the relative position of the binding source</span></div>
<div style="position:absolute;left:5.00px;top:540.75px" class="cls_004"><span class="cls_004">compared to the binding target, is optional here. Using the </span><span class="cls_007">AncestorType</span><span class="cls_004"> property implicitly</span></div>
<div style="position:absolute;left:5.00px;top:558.75px" class="cls_004"><span class="cls_004">sets the </span><span class="cls_007">Mode</span><span class="cls_004"> property to the </span><span class="cls_007">FindAncestor</span><span class="cls_004"> instance, so we can declare the same binding</span></div>
<div style="position:absolute;left:5.00px;top:576.75px" class="cls_004"><span class="cls_004">without it, like this:</span></div>
<div style="position:absolute;left:52.98px;top:600.00px" class="cls_007"><span class="cls_007"><TextBlock Text="{Binding DataContext.UserCount,</span></div>
<div style="position:absolute;left:67.97px;top:613.50px" class="cls_007"><span class="cls_007">RelativeSource={RelativeSource</span></div>
<div style="position:absolute;left:67.97px;top:627.00px" class="cls_007"><span class="cls_007">AncestorType={x:Type Views:UserView}}}" /></span></div>
<div style="position:absolute;left:5.00px;top:647.25px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">Mode</span><span class="cls_004"> property is of the </span><span class="cls_007">RelativeSourceMode</span><span class="cls_004"> enumeration type, which has four</span></div>
<div style="position:absolute;left:5.00px;top:665.25px" class="cls_004"><span class="cls_004">members. We've already seen an example of one instance, the </span><span class="cls_007">FindAncestor</span><span class="cls_004"> member,</span></div>
<div style="position:absolute;left:5.00px;top:683.25px" class="cls_004"><span class="cls_004">although this can be extended using the related </span><span class="cls_007">RelativeSource.AncestorLevel</span><span class="cls_004"> property,</span></div>
<div style="position:absolute;left:5.00px;top:701.25px" class="cls_004"><span class="cls_004">which specifies which level of ancestor in which to look for the binding source. This property</span></div>
<div style="position:absolute;left:5.00px;top:719.25px" class="cls_004"><span class="cls_004">is only really useful if a control has multiple ancestors of the same type, as in this following</span></div>
<div style="position:absolute;left:5.00px;top:737.25px" class="cls_004"><span class="cls_004">simplified example:</span></div>
<div style="position:absolute;left:52.98px;top:760.50px" class="cls_007"><span class="cls_007"><StackPanel Tag="Outer"></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:103458px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background131.jpg" width=612 height=792></div>
<div style="position:absolute;left:67.97px;top:16.50px" class="cls_007"><span class="cls_007"><StackPanel Orientation="Horizontal" Tag="Inner"></span></div>
<div style="position:absolute;left:82.97px;top:30.00px" class="cls_007"><span class="cls_007"><TextBlock Text="{Binding Tag, RelativeSource={RelativeSource</span></div>
<div style="position:absolute;left:97.96px;top:43.50px" class="cls_007"><span class="cls_007">Mode=FindAncestor, AncestorType={x:Type StackPanel},</span></div>
<div style="position:absolute;left:97.96px;top:57.00px" class="cls_007"><span class="cls_007">AncestorLevel=2}}" /></span></div>
<div style="position:absolute;left:67.97px;top:84.00px" class="cls_007"><span class="cls_007"></StackPanel></span></div>
<div style="position:absolute;left:52.98px;top:97.50px" class="cls_007"><span class="cls_007"></StackPanel></span></div>
<div style="position:absolute;left:5.00px;top:117.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">TextBox</span><span class="cls_004"> in this example will output the word </span><span class="cls_007">"Outer"</span><span class="cls_004"> at runtime, because we have</span></div>
<div style="position:absolute;left:5.00px;top:135.75px" class="cls_004"><span class="cls_004">declared that the binding source should be the second ancestor of type </span><span class="cls_007">StackPanel</span><span class="cls_004">. If the</span></div>
<div style="position:absolute;left:5.00px;top:153.75px" class="cls_007"><span class="cls_007">AncestorLevel</span><span class="cls_004"> property had been set to one, or omitted from the binding, then the </span><span class="cls_007">TextBox</span></div>
<div style="position:absolute;left:5.00px;top:171.75px" class="cls_004"><span class="cls_004">would output the word </span><span class="cls_007">"Inner"</span><span class="cls_004"> at runtime.</span></div>
<div style="position:absolute;left:5.00px;top:189.75px" class="cls_004"><span class="cls_004">The next </span><span class="cls_007">RelativeSourceMode</span><span class="cls_004"> enumeration instance is </span><span class="cls_007">Self</span><span class="cls_004">, which specifies that the binding</span></div>
<div style="position:absolute;left:5.00px;top:207.75px" class="cls_004"><span class="cls_004">source is the same object as the binding target. Note that when using the </span><span class="cls_007">RelativeSource</span></div>
<div style="position:absolute;left:5.00px;top:225.75px" class="cls_007"><span class="cls_007">.Self</span><span class="cls_004"> property, the </span><span class="cls_007">Mode</span><span class="cls_004"> property is implicitly set to the </span><span class="cls_007">Self</span><span class="cls_004"> instance. We could use this</span></div>
<div style="position:absolute;left:5.00px;top:243.75px" class="cls_004"><span class="cls_004">property to data bind one property of a UI control to another, as in this following example</span></div>
<div style="position:absolute;left:5.00px;top:261.75px" class="cls_004"><span class="cls_004">that sets the control's width value to its </span><span class="cls_007">Height</span><span class="cls_004"> property to ensure that it remains a square</span></div>
<div style="position:absolute;left:5.00px;top:279.75px" class="cls_004"><span class="cls_004">regardless of the width.</span></div>
<div style="position:absolute;left:52.98px;top:303.00px" class="cls_007"><span class="cls_007"><Rectangle Height="{Binding ActualWidth,</span></div>
<div style="position:absolute;left:67.97px;top:316.50px" class="cls_007"><span class="cls_007">RelativeSource={RelativeSource Self}}" Fill="Red" /></span></div>
<div style="position:absolute;left:5.00px;top:336.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">RelativeSource.TemplatedParent</span><span class="cls_004"> property is only used to access the properties of</span></div>
<div style="position:absolute;left:5.00px;top:354.75px" class="cls_004"><span class="cls_004">controls from inside a </span><span class="cls_007">ControlTemplate</span><span class="cls_004">. The templated parent refers to the object that has</span></div>
<div style="position:absolute;left:5.00px;top:372.75px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">ControlTemplate</span><span class="cls_004"> applied to it. When using the </span><span class="cls_007">TemplatedParent</span><span class="cls_004"> property, the </span><span class="cls_007">Mode</span></div>
<div style="position:absolute;left:5.00px;top:390.75px" class="cls_004"><span class="cls_004">property is implicitly set to the </span><span class="cls_007">TemplatedParent</span><span class="cls_004"> instance of the </span><span class="cls_007">RelativeSourceMode</span></div>
<div style="position:absolute;left:5.00px;top:408.75px" class="cls_004"><span class="cls_004">enumeration. Let's see an example.</span></div>
<div style="position:absolute;left:52.98px;top:432.00px" class="cls_007"><span class="cls_007"><ControlTemplate x:Key="ProgressBar" TargetType="{x:Type</span></div>
<div style="position:absolute;left:52.98px;top:445.50px" class="cls_007"><span class="cls_007">ProgressBar}"></span></div>
<div style="position:absolute;left:67.97px;top:472.50px" class="cls_007"><span class="cls_007"><TextBlock Text="{Binding Value,</span></div>
<div style="position:absolute;left:82.97px;top:486.00px" class="cls_007"><span class="cls_007">RelativeSource={RelativeSource TemplatedParent}}" /></span></div>
<div style="position:absolute;left:52.98px;top:513.00px" class="cls_007"><span class="cls_007"></ControlTemplate></span></div>
<div style="position:absolute;left:5.00px;top:533.25px" class="cls_004"><span class="cls_004">In this example, the templated parent is the instance of the </span><span class="cls_007">ProgressBar</span><span class="cls_004"> that will have this</span></div>
<div style="position:absolute;left:5.00px;top:551.25px" class="cls_004"><span class="cls_004">template applied to it and so, using the </span><span class="cls_007">TemplatedParent</span><span class="cls_004"> property, we are able to access</span></div>
<div style="position:absolute;left:5.00px;top:569.25px" class="cls_004"><span class="cls_004">the various properties of the </span><span class="cls_007">ProgressBar</span><span class="cls_004"> class from within the </span><span class="cls_007">ControlTemplate</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:587.25px" class="cls_004"><span class="cls_004">Furthermore, any binding source that is data bound to the </span><span class="cls_007">Value</span><span class="cls_004"> property of the templated</span></div>
<div style="position:absolute;left:5.00px;top:605.25px" class="cls_004"><span class="cls_004">parent will also be data bound to the </span><span class="cls_007">Text</span><span class="cls_004"> property of this internal </span><span class="cls_007">TextBox</span><span class="cls_004"> element.</span></div>
<div style="position:absolute;left:5.00px;top:623.25px" class="cls_004"><span class="cls_004">Moving on to the final </span><span class="cls_007">RelativeSource</span><span class="cls_004"> property, </span><span class="cls_007">PreviousData</span><span class="cls_004"> is only really useful when</span></div>
<div style="position:absolute;left:5.00px;top:641.25px" class="cls_004"><span class="cls_004">defining a </span><span class="cls_007">DataTemplate</span><span class="cls_004"> for items in a collection. It is used to set the previous item in the</span></div>
<div style="position:absolute;left:5.00px;top:659.25px" class="cls_004"><span class="cls_004">collection as the binding source. While not often used, there can be situations where we</span></div>
<div style="position:absolute;left:5.00px;top:677.25px" class="cls_004"><span class="cls_004">need to compare values between neighboring items in a collection and we'll see a full</span></div>
<div style="position:absolute;left:5.00px;top:695.25px" class="cls_004"><span class="cls_004">example of this later in this chapter.</span></div>
<div style="position:absolute;left:5.00px;top:713.25px" class="cls_004"><span class="cls_004">Although a far simpler option, the </span><span class="cls_007">ElementName</span><span class="cls_004"> property of the </span><span class="cls_007">Binding</span><span class="cls_004"> class also enables</span></div>
<div style="position:absolute;left:5.00px;top:731.25px" class="cls_004"><span class="cls_004">us to override the binding source set by the </span><span class="cls_007">DataContext</span><span class="cls_004">. It is used to data bind the</span></div>
<div style="position:absolute;left:5.00px;top:749.25px" class="cls_004"><span class="cls_004">property of one UI control to either the property of another control, or another property on</span></div>
<div style="position:absolute;left:5.00px;top:767.25px" class="cls_004"><span class="cls_004">the same control. The only requirement to use this property is that we need to name the</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:104260px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background132.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">element that we want to data bind to in our current control. Let's see an example.</span></div>
<div style="position:absolute;left:52.98px;top:27.00px" class="cls_007"><span class="cls_007"><StackPanel Orientation="Horizontal" TextElement.FontSize="24"</span></div>
<div style="position:absolute;left:52.98px;top:40.50px" class="cls_007"><span class="cls_007">Margin="20"></span></div>
<div style="position:absolute;left:67.97px;top:54.00px" class="cls_007"><span class="cls_007"><CheckBox Name="Checkbox" Content="Service" Margin="0,0,10,0" /></span></div>
<div style="position:absolute;left:67.97px;top:67.50px" class="cls_007"><span class="cls_007"><TextBox Text="{Binding Service}"</span></div>
<div style="position:absolute;left:82.97px;top:81.00px" class="cls_007"><span class="cls_007">Visibility="{Binding IsChecked, ElementName=Checkbox,</span></div>
<div style="position:absolute;left:82.97px;top:94.50px" class="cls_007"><span class="cls_007">Converter={StaticResource BoolToVisibilityConverter}}" /></span></div>
<div style="position:absolute;left:52.98px;top:108.00px" class="cls_007"><span class="cls_007"></StackPanel></span></div>
<div style="position:absolute;left:5.00px;top:128.25px" class="cls_004"><span class="cls_004">In this example, we have a service </span><span class="cls_007">CheckBox</span><span class="cls_004"> and a </span><span class="cls_007">TextBlock</span><span class="cls_004">. The </span><span class="cls_007">Visibility</span><span class="cls_004"> property of</span></div>
<div style="position:absolute;left:5.00px;top:146.25px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">TextBlock</span><span class="cls_004"> is data bound to the </span><span class="cls_007">IsChecked</span><span class="cls_004"> property of the </span><span class="cls_007">CheckBox</span><span class="cls_004"> and we make use</span></div>
<div style="position:absolute;left:5.00px;top:164.25px" class="cls_004"><span class="cls_004">of the </span><span class="cls_007">BoolToVisibilityConverter</span><span class="cls_004"> class that we saw earlier to convert the </span><span class="cls_007">bool</span><span class="cls_004"> value to a</span></div>
<div style="position:absolute;left:5.00px;top:182.25px" class="cls_007"><span class="cls_007">Visibility</span><span class="cls_004"> instance. Therefore, when the user checks the checkbox, the textbox will</span></div>
<div style="position:absolute;left:5.00px;top:200.25px" class="cls_004"><span class="cls_004">become visible and vice versa.</span></div>
<div style="position:absolute;left:5.00px;top:218.25px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">ElementName</span><span class="cls_004"> property can also be used as a shortcut to accessing the parent control's</span></div>
<div style="position:absolute;left:5.00px;top:236.25px" class="cls_007"><span class="cls_007">DataContext</span><span class="cls_004">. If we name our View </span><span class="cls_007">This</span><span class="cls_004"> for example, then we can use the </span><span class="cls_007">ElementName</span></div>
<div style="position:absolute;left:5.00px;top:254.25px" class="cls_004"><span class="cls_004">property from within a data template to data bind to a property from the parent View</span></div>
<div style="position:absolute;left:5.00px;top:272.25px" class="cls_004"><span class="cls_004">Model.</span></div>
<div style="position:absolute;left:52.98px;top:295.50px" class="cls_007"><span class="cls_007"><DataTemplate DataType="{x:Type DataModels:User}"></span></div>
<div style="position:absolute;left:67.97px;top:309.00px" class="cls_007"><span class="cls_007"><StackPanel></span></div>
<div style="position:absolute;left:82.97px;top:322.50px" class="cls_007"><span class="cls_007"><TextBlock Text="{Binding Name}" /></span></div>
<div style="position:absolute;left:82.97px;top:336.00px" class="cls_007"><span class="cls_007"><TextBlock Text="{Binding DataContext.UserCount,</span></div>
<div style="position:absolute;left:52.98px;top:349.50px" class="cls_007"><span class="cls_007">ElementName=This}" /></span></div>
<div style="position:absolute;left:67.97px;top:363.00px" class="cls_007"><span class="cls_007"></StackPanel></span></div>
<div style="position:absolute;left:52.98px;top:376.50px" class="cls_007"><span class="cls_007"></DataTemplate></span></div>
<div style="position:absolute;left:5.00px;top:396.75px" class="cls_004"><span class="cls_004">When specifying these alternative binding sources, it is important to know that we can only</span></div>
<div style="position:absolute;left:5.00px;top:414.75px" class="cls_004"><span class="cls_004">use one of these three different methods at once. If we were to set more than one of the</span></div>
<div style="position:absolute;left:5.00px;top:432.75px" class="cls_004"><span class="cls_004">binding </span><span class="cls_007">Source</span><span class="cls_004">, </span><span class="cls_007">RelativeSource</span><span class="cls_004">, or </span><span class="cls_007">ElementName</span><span class="cls_004"> properties, then an exception would be</span></div>
<div style="position:absolute;left:5.00px;top:450.75px" class="cls_004"><span class="cls_004">thrown from the binding.</span></div>
<div style="position:absolute;left:5.00px;top:468.01px" class="cls_011"><span class="cls_011">Binding with priority</span></div>
<div style="position:absolute;left:5.00px;top:498.00px" class="cls_004"><span class="cls_004">On the odd occasion, we may need to specify a number of source binding paths and want</span></div>
<div style="position:absolute;left:5.00px;top:516.00px" class="cls_004"><span class="cls_004">to map them to a single binding target property. One way that we can do this is to use the</span></div>
<div style="position:absolute;left:5.00px;top:534.00px" class="cls_007"><span class="cls_007">MultiBinding</span><span class="cls_004"> class and we'll see an example of this in the last section of this chapter.</span></div>
<div style="position:absolute;left:5.00px;top:552.00px" class="cls_004"><span class="cls_004">However, there is an alternative class that we can use that provides us with some additional</span></div>
<div style="position:absolute;left:5.00px;top:570.00px" class="cls_004"><span class="cls_004">functionality.</span></div>
<div style="position:absolute;left:5.00px;top:588.00px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">PriorityBinding</span><span class="cls_004"> class enables us to specify multiple bindings and gives each a</span></div>
<div style="position:absolute;left:5.00px;top:606.00px" class="cls_004"><span class="cls_004">priority, with the bindings that are declared first having the highest priority. The special</span></div>
<div style="position:absolute;left:5.00px;top:624.00px" class="cls_004"><span class="cls_004">functionality of this class is that it will display the value from the first binding that returns a</span></div>
<div style="position:absolute;left:5.00px;top:642.00px" class="cls_004"><span class="cls_004">valid value and if that is not the binding with the highest priority, it will then update the</span></div>
<div style="position:absolute;left:5.00px;top:660.00px" class="cls_004"><span class="cls_004">display with the value from the highest priority binding when it is successfully resolved.</span></div>
<div style="position:absolute;left:5.00px;top:678.00px" class="cls_004"><span class="cls_004">To clarify further, this enables us to specify a binding to a normal property that will resolve</span></div>
<div style="position:absolute;left:5.00px;top:696.00px" class="cls_004"><span class="cls_004">immediately, while the actual value that we want to data bind to is being downloaded,</span></div>
<div style="position:absolute;left:5.00px;top:714.00px" class="cls_004"><span class="cls_004">calculated, or otherwise being resolved over time. This enables us to supply a default image</span></div>
<div style="position:absolute;left:5.00px;top:732.00px" class="cls_004"><span class="cls_004">source while the actual required image is being downloaded, or to output a message until a</span></div>
<div style="position:absolute;left:5.00px;top:750.00px" class="cls_004"><span class="cls_004">calculated value is ready for display. Let's look at a simple XAML example.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:105062px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background133.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:9.00px" class="cls_007"><span class="cls_007"><TextBlock></span></div>
<div style="position:absolute;left:67.97px;top:22.50px" class="cls_007"><span class="cls_007"><TextBlock.Text></span></div>
<div style="position:absolute;left:82.97px;top:36.00px" class="cls_007"><span class="cls_007"><PriorityBinding></span></div>
<div style="position:absolute;left:97.96px;top:49.50px" class="cls_007"><span class="cls_007"><Binding Path="SlowString" IsAsync="True" /></span></div>
<div style="position:absolute;left:97.96px;top:63.00px" class="cls_007"><span class="cls_007"><Binding Path="FastString" Mode="OneWay" /></span></div>
<div style="position:absolute;left:82.97px;top:76.50px" class="cls_007"><span class="cls_007"></PriorityBinding></span></div>
<div style="position:absolute;left:67.97px;top:90.00px" class="cls_007"><span class="cls_007"></TextBlock.Text></span></div>
<div style="position:absolute;left:52.98px;top:103.50px" class="cls_007"><span class="cls_007"></TextBlock></span></div>
<div style="position:absolute;left:5.00px;top:123.75px" class="cls_004"><span class="cls_004">In the preceding example, we set the </span><span class="cls_007">PriorityBinding</span><span class="cls_004"> on the </span><span class="cls_007">TextBlock.Text</span><span class="cls_004"> property</span></div>
<div style="position:absolute;left:5.00px;top:141.75px" class="cls_004"><span class="cls_004">and inside, specify two bindings. The first has the higher priority and has the actual property</span></div>
<div style="position:absolute;left:5.00px;top:159.75px" class="cls_004"><span class="cls_004">value that we want to display. Note that we set the </span><span class="cls_007">IsAsync</span><span class="cls_004"> property to </span><span class="cls_007">True</span><span class="cls_004">, to specify that</span></div>
<div style="position:absolute;left:5.00px;top:177.75px" class="cls_004"><span class="cls_004">this binding will take some time to resolve and that it should not block the UI thread.</span></div>
<div style="position:absolute;left:5.00px;top:195.75px" class="cls_004"><span class="cls_004">The second binding is data bound to a normal property using a One-Way binding that simply</span></div>
<div style="position:absolute;left:5.00px;top:213.75px" class="cls_004"><span class="cls_004">outputs a message.</span></div>
<div style="position:absolute;left:52.98px;top:237.00px" class="cls_007"><span class="cls_007">public string FastString</span></div>
<div style="position:absolute;left:52.98px;top:250.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:264.00px" class="cls_007"><span class="cls_007">get { return "The value is being calculated..."; }</span></div>
<div style="position:absolute;left:52.98px;top:277.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:297.75px" class="cls_004"><span class="cls_004">By using the </span><span class="cls_007">PriorityBinding</span><span class="cls_004"> element, this message will be output instantly and then</span></div>
<div style="position:absolute;left:5.00px;top:315.75px" class="cls_004"><span class="cls_004">updated with the actual value from the </span><span class="cls_007">SlowString</span><span class="cls_004"> property when it is ready. Let's now</span></div>
<div style="position:absolute;left:5.00px;top:333.75px" class="cls_004"><span class="cls_004">move on and investigate one further type of </span><span class="cls_007">Binding</span><span class="cls_004"> class.</span></div>
<div style="position:absolute;left:5.00px;top:351.01px" class="cls_011"><span class="cls_011">Binding from within control templates</span></div>
<div style="position:absolute;left:5.00px;top:381.00px" class="cls_004"><span class="cls_004">A </span><span class="cls_007">TemplateBinding</span><span class="cls_004"> is a particular type of binding that is used within </span><span class="cls_007">ControlTemplate</span></div>
<div style="position:absolute;left:5.00px;top:399.00px" class="cls_004"><span class="cls_004">elements in order to data bind to the properties of the type that is being templated. It is</span></div>
<div style="position:absolute;left:5.00px;top:417.00px" class="cls_004"><span class="cls_004">very similar to the </span><span class="cls_007">RelativeSource.TemplatedParent</span><span class="cls_004"> property that we discussed earlier. It's</span></div>
<div style="position:absolute;left:5.00px;top:435.00px" class="cls_004"><span class="cls_004">a way to connect the properties of elements inside a </span><span class="cls_007">ControlTemplate</span><span class="cls_004"> to the properties of</span></div>
<div style="position:absolute;left:5.00px;top:453.00px" class="cls_004"><span class="cls_004">elements outside the template.</span></div>
<div style="position:absolute;left:52.98px;top:476.25px" class="cls_007"><span class="cls_007"><ControlTemplate x:Key="ProgressBar" TargetType="{x:Type</span></div>
<div style="position:absolute;left:52.98px;top:489.75px" class="cls_007"><span class="cls_007">ProgressBar}"></span></div>
<div style="position:absolute;left:67.97px;top:516.75px" class="cls_007"><span class="cls_007"><TextBlock Text="{TemplateBinding Value}" /></span></div>
<div style="position:absolute;left:52.98px;top:543.75px" class="cls_007"><span class="cls_007"></ControlTemplate></span></div>
<div style="position:absolute;left:5.00px;top:564.00px" class="cls_004"><span class="cls_004">In this example from earlier that we edited slightly, we see that declaring a</span></div>
<div style="position:absolute;left:5.00px;top:582.00px" class="cls_007"><span class="cls_007">TemplateBinding</span><span class="cls_004"> is far more straightforward and less verbose than performing the same</span></div>
<div style="position:absolute;left:5.00px;top:600.00px" class="cls_004"><span class="cls_004">binding using the </span><span class="cls_007">RelativeSource.TemplatedParent</span><span class="cls_004"> property. Let's remind ourselves what</span></div>
<div style="position:absolute;left:5.00px;top:618.00px" class="cls_004"><span class="cls_004">that looked like.</span></div>
<div style="position:absolute;left:52.98px;top:641.25px" class="cls_007"><span class="cls_007"><TextBlock Text="{Binding Value,</span></div>
<div style="position:absolute;left:67.97px;top:654.75px" class="cls_007"><span class="cls_007">RelativeSource={RelativeSource TemplatedParent}}" /></span></div>
<div style="position:absolute;left:5.00px;top:675.00px" class="cls_004"><span class="cls_004">It is generally preferable to use a </span><span class="cls_007">TemplateBinding</span><span class="cls_004"> instead of the</span></div>
<div style="position:absolute;left:5.00px;top:693.00px" class="cls_007"><span class="cls_007">RelativeSource.TemplatedParent</span><span class="cls_004"> property and although they perform the same connection</span></div>
<div style="position:absolute;left:5.00px;top:711.00px" class="cls_004"><span class="cls_004">in the binding, there are a few differences between them. For example, a </span><span class="cls_007">TemplateBinding</span></div>
<div style="position:absolute;left:5.00px;top:729.00px" class="cls_004"><span class="cls_004">is evaluated at compile time, whereas </span><span class="cls_007">TemplateBinding</span><span class="cls_004"> is not evaluated until runtime. It can</span></div>
<div style="position:absolute;left:5.00px;top:747.00px" class="cls_004"><span class="cls_004">therefore also make it easier to work with.</span></div>
<div style="position:absolute;left:5.00px;top:765.00px" class="cls_004"><span class="cls_004">Furthermore, it is a simpler form of binding and is missing a number of the </span><span class="cls_007">Binding</span><span class="cls_004"> class</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:105864px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background134.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">properties, such as </span><span class="cls_007">StringFormat</span><span class="cls_004"> and </span><span class="cls_007">Delay</span><span class="cls_004">. In addition, it places the extra constraints on</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">the user, that it is permanently set to have a binding mode of </span><span class="cls_007">OneWay</span><span class="cls_004"> and both binding target</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_006"><span class="cls_006">and</span><span class="cls_004"> binding source must be Dependency Properties. It was designed to be used in a single</span></div>
<div style="position:absolute;left:5.00px;top:58.50px" class="cls_004"><span class="cls_004">place with a single purpose and in that situation, it does its job well and more efficiently than</span></div>
<div style="position:absolute;left:5.00px;top:76.50px" class="cls_004"><span class="cls_004">its counterpart.</span></div>
<div style="position:absolute;left:5.00px;top:93.76px" class="cls_011"><span class="cls_011">Binding source changes</span></div>
<div style="position:absolute;left:5.00px;top:123.75px" class="cls_004"><span class="cls_004">At times, we may need to make changes to our binding sources and have those changes</span></div>
<div style="position:absolute;left:5.00px;top:141.75px" class="cls_004"><span class="cls_004">propagate to the binding target controls. We may want to set default values on a new form,</span></div>
<div style="position:absolute;left:5.00px;top:159.75px" class="cls_004"><span class="cls_004">clear old form values, or even set form labels from our View Models. In order to do this, our</span></div>
<div style="position:absolute;left:5.00px;top:177.75px" class="cls_004"><span class="cls_004">View Models </span><span class="cls_006">must</span><span class="cls_004"> implement the </span><span class="cls_007">INotifyPropertyChanged</span><span class="cls_004"> interface and this is why we</span></div>
<div style="position:absolute;left:5.00px;top:196.50px" class="cls_004"><span class="cls_004">build this implementation into our base View Model class.</span></div>
<div style="position:absolute;left:5.00px;top:214.50px" class="cls_004"><span class="cls_004">When we data bind a binding source to a control in the UI, an event handler is attached to</span></div>
<div style="position:absolute;left:5.00px;top:232.50px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">PropertyChanged</span><span class="cls_004"> event of the source object. When a notification of a change to the</span></div>
<div style="position:absolute;left:5.00px;top:250.50px" class="cls_004"><span class="cls_004">property that is specified by the binding source property path is received, the control is</span></div>
<div style="position:absolute;left:5.00px;top:268.50px" class="cls_004"><span class="cls_004">updated with the new value.</span></div>
<div style="position:absolute;left:5.00px;top:286.50px" class="cls_004"><span class="cls_004">It should be noted that the </span><span class="cls_007">PropertyChanged</span><span class="cls_004"> event of the binding source will be null if no</span></div>
<div style="position:absolute;left:5.00px;top:304.50px" class="cls_004"><span class="cls_004">handler has specifically been attached and none of its properties have been data bound to</span></div>
<div style="position:absolute;left:5.00px;top:322.50px" class="cls_004"><span class="cls_004">UI controls. It is for this reason that we must always check for null, before raising this</span></div>
<div style="position:absolute;left:5.00px;top:340.50px" class="cls_004"><span class="cls_004">event.</span></div>
<div style="position:absolute;left:5.00px;top:358.50px" class="cls_004"><span class="cls_004">All of the binding modes work in the direction of binding source to binding target, except for</span></div>
<div style="position:absolute;left:5.00px;top:376.50px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">OneWayToSource</span><span class="cls_004"> instance. However, only this and the </span><span class="cls_007">TwoWay</span><span class="cls_004"> instance of the</span></div>
<div style="position:absolute;left:5.00px;top:394.50px" class="cls_007"><span class="cls_007">Binding.Mode</span><span class="cls_004"> enumeration propagate changes in the direction of the binding target to the</span></div>
<div style="position:absolute;left:5.00px;top:412.50px" class="cls_004"><span class="cls_004">binding source.</span></div>
<div style="position:absolute;left:5.00px;top:430.50px" class="cls_004"><span class="cls_004">When the binding is working in either of these modes, it attaches a handler to the target</span></div>
<div style="position:absolute;left:5.00px;top:448.50px" class="cls_004"><span class="cls_004">control to listen for changes to the target property. When it receives notification of a change</span></div>
<div style="position:absolute;left:5.00px;top:466.50px" class="cls_004"><span class="cls_004">to the target property, its behavior is determined by the value of the binding's</span></div>
<div style="position:absolute;left:5.00px;top:484.50px" class="cls_007"><span class="cls_007">UpdateSourceTrigger</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:5.00px;top:502.50px" class="cls_004"><span class="cls_004">This property is of the enumeration type </span><span class="cls_007">UpdateSourceTrigger</span><span class="cls_004">, which has four members.</span></div>
<div style="position:absolute;left:5.00px;top:520.50px" class="cls_004"><span class="cls_004">The most common is the </span><span class="cls_007">PropertyChanged</span><span class="cls_004"> instance and this specifies that the source</span></div>
<div style="position:absolute;left:5.00px;top:538.50px" class="cls_004"><span class="cls_004">property should be updated as soon as the target property has changed. This is the default</span></div>
<div style="position:absolute;left:5.00px;top:556.50px" class="cls_004"><span class="cls_004">value for most controls.</span></div>
<div style="position:absolute;left:5.00px;top:574.50px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">LostFocus</span><span class="cls_004"> member is the next most common value and this specifies that the binding</span></div>
<div style="position:absolute;left:5.00px;top:592.50px" class="cls_004"><span class="cls_004">should update the binding source when the user moves focus from the data bound control.</span></div>
<div style="position:absolute;left:5.00px;top:610.50px" class="cls_004"><span class="cls_004">This option can be useful when we want to trigger validation once the user has completed</span></div>
<div style="position:absolute;left:5.00px;top:628.50px" class="cls_004"><span class="cls_004">entry in each textbox, rather than as they type.</span></div>
<div style="position:absolute;left:5.00px;top:646.50px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">Explicit</span><span class="cls_004"> instance will not update the binding source without explicit instruction to do</span></div>
<div style="position:absolute;left:5.00px;top:664.50px" class="cls_004"><span class="cls_004">so. As we need to programmatically call the </span><span class="cls_007">UpdateSource</span><span class="cls_004"> method of the internal</span></div>
<div style="position:absolute;left:5.00px;top:682.50px" class="cls_007"><span class="cls_007">BindingExpression</span><span class="cls_004"> object in order to propagate the changes to the binding source, this</span></div>
<div style="position:absolute;left:5.00px;top:700.50px" class="cls_004"><span class="cls_004">option is not generally used in our normal Views.</span></div>
<div style="position:absolute;left:5.00px;top:718.50px" class="cls_004"><span class="cls_004">Instead, if used at all, we would find it in our </span><span class="cls_007">CustomControl</span><span class="cls_004"> classes. Note that calling the</span></div>
<div style="position:absolute;left:5.00px;top:736.50px" class="cls_007"><span class="cls_007">UpdateSource</span><span class="cls_004"> method will do nothing if the binding mode is not set to one of the</span></div>
<div style="position:absolute;left:5.00px;top:754.50px" class="cls_007"><span class="cls_007">OneWayToSource</span><span class="cls_004"> or </span><span class="cls_007">TwoWay</span><span class="cls_004"> instances.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:106666px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background135.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">If we had an instance of a textbox and we wanted to explicitly update the binding source</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">that was data bound to its </span><span class="cls_007">Text</span><span class="cls_004"> property, we can access the lower-level</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_007"><span class="cls_007">BindingExpression</span><span class="cls_004"> object from the </span><span class="cls_007">BindingOperations.GetBindingExpression</span><span class="cls_004"> method and</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">call its </span><span class="cls_007">UpdateSource</span><span class="cls_004"> method.</span></div>
<div style="position:absolute;left:52.98px;top:81.00px" class="cls_007"><span class="cls_007">BindingExpression bindingExpression =</span></div>
<div style="position:absolute;left:67.97px;top:94.50px" class="cls_007"><span class="cls_007">BindingOperations.GetBindingExpression(textBox,</span></div>
<div style="position:absolute;left:52.98px;top:108.00px" class="cls_007"><span class="cls_007">TextBox.TextProperty);</span></div>
<div style="position:absolute;left:52.98px;top:121.50px" class="cls_007"><span class="cls_007">bindingExpression.UpdateSource();</span></div>
<div style="position:absolute;left:5.00px;top:141.75px" class="cls_004"><span class="cls_004">Alternatively, if our binding target control class extends the </span><span class="cls_007">FrameworkElement</span><span class="cls_004"> class and</span></div>
<div style="position:absolute;left:5.00px;top:159.75px" class="cls_004"><span class="cls_004">most do, then we can simply call the </span><span class="cls_007">GetBindingExpression</span><span class="cls_004"> method on it directly and pass</span></div>
<div style="position:absolute;left:5.00px;top:177.75px" class="cls_004"><span class="cls_004">in the Dependency Property key that we want to update the binding from.</span></div>
<div style="position:absolute;left:52.98px;top:201.00px" class="cls_007"><span class="cls_007">textBox.GetBindingExpression(TextBox.TextProperty);</span></div>
<div style="position:absolute;left:5.00px;top:221.25px" class="cls_004"><span class="cls_004">The last member of the </span><span class="cls_007">UpdateSourceTrigger</span><span class="cls_004"> enumeration is the </span><span class="cls_007">Default</span><span class="cls_004"> instance. This is</span></div>
<div style="position:absolute;left:5.00px;top:239.25px" class="cls_004"><span class="cls_004">similar to the </span><span class="cls_007">Default</span><span class="cls_004"> instance of the </span><span class="cls_007">Binding.Mode</span><span class="cls_004"> enumeration in that it uses the value</span></div>
<div style="position:absolute;left:5.00px;top:257.25px" class="cls_004"><span class="cls_004">specified by each target Dependency Property and is the default value of the</span></div>
<div style="position:absolute;left:5.00px;top:275.25px" class="cls_007"><span class="cls_007">UpdateSourceTrigger</span><span class="cls_004"> property. Again, we'll find out how to set the metadata for</span></div>
<div style="position:absolute;left:5.00px;top:293.25px" class="cls_004"><span class="cls_004">Dependency Properties later in this chapter.</span></div>
<div style="position:absolute;left:5.00px;top:310.51px" class="cls_011"><span class="cls_011">Converting data bound values</span></div>
<div style="position:absolute;left:5.00px;top:340.50px" class="cls_004"><span class="cls_004">There are many times when developing a WPF application, when we need to convert a data</span></div>
<div style="position:absolute;left:5.00px;top:358.50px" class="cls_004"><span class="cls_004">bound property value to a different type. For example, we might want to control the visibility</span></div>
<div style="position:absolute;left:5.00px;top:376.50px" class="cls_004"><span class="cls_004">of some UI elements with a </span><span class="cls_007">bool</span><span class="cls_004"> property in our View Model, so that we can avoid having</span></div>
<div style="position:absolute;left:5.00px;top:394.50px" class="cls_004"><span class="cls_004">the UI-related </span><span class="cls_007">Visibility</span><span class="cls_004"> enumeration instance in it.</span></div>
<div style="position:absolute;left:5.00px;top:412.50px" class="cls_004"><span class="cls_004">We might want to convert different enumeration members to different </span><span class="cls_007">Brush</span><span class="cls_004"> objects, or</span></div>
<div style="position:absolute;left:5.00px;top:430.50px" class="cls_004"><span class="cls_004">collections to string representations of the contained collection items. We've already seen a</span></div>
<div style="position:absolute;left:5.00px;top:448.50px" class="cls_004"><span class="cls_004">number of examples of the </span><span class="cls_007">IValueConverter</span><span class="cls_004"> interface, but let's now take a bit more of a</span></div>
<div style="position:absolute;left:5.00px;top:466.50px" class="cls_004"><span class="cls_004">thorough look.</span></div>
<div style="position:absolute;left:52.98px;top:489.75px" class="cls_007"><span class="cls_007">public interface IValueConverter</span></div>
<div style="position:absolute;left:52.98px;top:503.25px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:516.75px" class="cls_007"><span class="cls_007">object Convert(object value, Type targetType, object parameter,</span></div>
<div style="position:absolute;left:82.97px;top:530.25px" class="cls_007"><span class="cls_007">CultureInfo culture);</span></div>
<div style="position:absolute;left:67.97px;top:543.75px" class="cls_007"><span class="cls_007">object ConvertBack(object value, Type targetType, object</span></div>
<div style="position:absolute;left:52.98px;top:557.25px" class="cls_007"><span class="cls_007">parameter,</span></div>
<div style="position:absolute;left:82.97px;top:570.75px" class="cls_007"><span class="cls_007">CultureInfo culture);</span></div>
<div style="position:absolute;left:52.98px;top:584.25px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:604.50px" class="cls_004"><span class="cls_004">As we've already seen, the </span><span class="cls_007">value</span><span class="cls_004"> input parameter of type </span><span class="cls_007">object</span><span class="cls_004"> is the data bound value of</span></div>
<div style="position:absolute;left:5.00px;top:622.50px" class="cls_004"><span class="cls_004">the binding. The </span><span class="cls_007">object</span><span class="cls_004"> return type relates to the converted value that we want to return.</span></div>
<div style="position:absolute;left:5.00px;top:640.50px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">targetType</span><span class="cls_004"> input parameter specifies the type of the binding target property and is</span></div>
<div style="position:absolute;left:5.00px;top:658.50px" class="cls_004"><span class="cls_004">typically used to validate the input value to ensure that the converter is being used with the</span></div>
<div style="position:absolute;left:5.00px;top:676.50px" class="cls_004"><span class="cls_004">expected type of data.</span></div>
<div style="position:absolute;left:5.00px;top:694.50px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">parameter</span><span class="cls_004"> input parameter is optionally used to pass an additional value through to the</span></div>
<div style="position:absolute;left:5.00px;top:712.50px" class="cls_004"><span class="cls_004">converter. If used, its value can be set using the </span><span class="cls_007">Binding.ConverterParameter</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:5.00px;top:730.50px" class="cls_004"><span class="cls_004">Finally, the </span><span class="cls_007">culture</span><span class="cls_004"> input parameter provides us with a </span><span class="cls_007">CultureInfo</span><span class="cls_004"> object to correctly</span></div>
<div style="position:absolute;left:5.00px;top:748.50px" class="cls_004"><span class="cls_004">format textual output, when working in a culturally-sensitive application. We'll return to this in</span></div>
<div style="position:absolute;left:5.00px;top:766.50px" class="cls_004"><span class="cls_004">a moment, but let's first look at an example of a converter that uses the </span><span class="cls_007">parameter</span><span class="cls_004"> input</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:107468px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background136.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">parameter.</span></div>
<div style="position:absolute;left:52.98px;top:27.00px" class="cls_007"><span class="cls_007">using System;</span></div>
<div style="position:absolute;left:52.98px;top:40.50px" class="cls_007"><span class="cls_007">using System.Globalization;</span></div>
<div style="position:absolute;left:52.98px;top:54.00px" class="cls_007"><span class="cls_007">using System.Windows;</span></div>
<div style="position:absolute;left:52.98px;top:67.50px" class="cls_007"><span class="cls_007">using System.Windows.Data;</span></div>
<div style="position:absolute;left:52.98px;top:94.50px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.Converters</span></div>
<div style="position:absolute;left:52.98px;top:108.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:121.50px" class="cls_007"><span class="cls_007">[ValueConversion(typeof(Enum), typeof(bool))]</span></div>
<div style="position:absolute;left:67.97px;top:135.00px" class="cls_007"><span class="cls_007">public class EnumToBoolConverter : IValueConverter</span></div>
<div style="position:absolute;left:67.97px;top:148.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:162.00px" class="cls_007"><span class="cls_007">public bool IsInverted { get; set; }</span></div>
<div style="position:absolute;left:82.97px;top:189.00px" class="cls_007"><span class="cls_007">public object Convert(object value, Type targetType, object</span></div>
<div style="position:absolute;left:52.98px;top:202.50px" class="cls_007"><span class="cls_007">parameter,</span></div>
<div style="position:absolute;left:97.96px;top:216.00px" class="cls_007"><span class="cls_007">CultureInfo culture)</span></div>
<div style="position:absolute;left:82.97px;top:229.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:243.00px" class="cls_007"><span class="cls_007">if (value == null || parameter == null || (value.GetType() !=</span></div>
<div style="position:absolute;left:112.96px;top:256.50px" class="cls_007"><span class="cls_007">typeof(Enum) && value.GetType().BaseType != typeof(Enum)))</span></div>
<div style="position:absolute;left:112.96px;top:270.00px" class="cls_007"><span class="cls_007">return DependencyProperty.UnsetValue;</span></div>
<div style="position:absolute;left:97.96px;top:283.50px" class="cls_007"><span class="cls_007">string enumValue = value.ToString();</span></div>
<div style="position:absolute;left:97.96px;top:297.00px" class="cls_007"><span class="cls_007">string targetValue = parameter.ToString();</span></div>
<div style="position:absolute;left:97.96px;top:310.50px" class="cls_007"><span class="cls_007">bool boolValue = enumValue.Equals(targetValue,</span></div>
<div style="position:absolute;left:112.96px;top:324.00px" class="cls_007"><span class="cls_007">StringComparison.InvariantCultureIgnoreCase);</span></div>
<div style="position:absolute;left:97.96px;top:337.50px" class="cls_007"><span class="cls_007">return IsInverted ? !boolValue : boolValue;</span></div>
<div style="position:absolute;left:82.97px;top:351.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:378.00px" class="cls_007"><span class="cls_007">public object ConvertBack(object value, Type targetType,</span></div>
<div style="position:absolute;left:97.96px;top:391.50px" class="cls_007"><span class="cls_007">object parameter, CultureInfo culture)</span></div>
<div style="position:absolute;left:82.97px;top:405.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:418.50px" class="cls_007"><span class="cls_007">if (value == null || parameter == null)</span></div>
<div style="position:absolute;left:112.96px;top:432.00px" class="cls_007"><span class="cls_007">return DependencyProperty.UnsetValue;</span></div>
<div style="position:absolute;left:97.96px;top:445.50px" class="cls_007"><span class="cls_007">bool boolValue = (bool)value;</span></div>
<div style="position:absolute;left:97.96px;top:459.00px" class="cls_007"><span class="cls_007">string targetValue = parameter.ToString();</span></div>
<div style="position:absolute;left:97.96px;top:472.50px" class="cls_007"><span class="cls_007">if ((boolValue && !IsInverted) || (!boolValue && IsInverted))</span></div>
<div style="position:absolute;left:112.96px;top:486.00px" class="cls_007"><span class="cls_007">return Enum.Parse(targetType, targetValue);</span></div>
<div style="position:absolute;left:97.96px;top:499.50px" class="cls_007"><span class="cls_007">return DependencyProperty.UnsetValue;</span></div>
<div style="position:absolute;left:82.97px;top:513.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:526.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:540.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:573.00px" class="cls_004"><span class="cls_004">The idea of this converter is that we can data bind an enumeration property to a</span></div>
<div style="position:absolute;left:5.00px;top:591.00px" class="cls_007"><span class="cls_007">RadioButton</span><span class="cls_004"> or </span><span class="cls_007">CheckBox</span><span class="cls_004"> control that specifies the name of a particular member. If the</span></div>
<div style="position:absolute;left:5.00px;top:609.00px" class="cls_004"><span class="cls_004">value of the data bound property matches the specified member, then the converter will</span></div>
<div style="position:absolute;left:5.00px;top:627.00px" class="cls_004"><span class="cls_004">return true and check the control. For all other enumeration members, the control will be</span></div>
<div style="position:absolute;left:5.00px;top:645.00px" class="cls_004"><span class="cls_004">unchecked. We could then specify a different member in each of a group of </span><span class="cls_007">RadioButton</span></div>
<div style="position:absolute;left:5.00px;top:663.00px" class="cls_004"><span class="cls_004">controls, so that each member could be set.</span></div>
<div style="position:absolute;left:5.00px;top:681.00px" class="cls_004"><span class="cls_004">In the class, we start by specifying the data types that are involved in the implementation of</span></div>
<div style="position:absolute;left:5.00px;top:699.00px" class="cls_004"><span class="cls_004">the converter in the </span><span class="cls_007">ValueConversion</span><span class="cls_004"> attribute. Next, we see the </span><span class="cls_007">IsInverted</span><span class="cls_004"> property that</span></div>
<div style="position:absolute;left:5.00px;top:717.00px" class="cls_004"><span class="cls_004">we saw in the </span><span class="cls_007">BaseVisibilityConverter</span><span class="cls_004"> class that enables us to invert the output of the</span></div>
<div style="position:absolute;left:5.00px;top:735.00px" class="cls_004"><span class="cls_004">converter.</span></div>
<div style="position:absolute;left:5.00px;top:753.00px" class="cls_004"><span class="cls_004">In the </span><span class="cls_007">Convert</span><span class="cls_004"> method, we first check the validity of our </span><span class="cls_007">value</span><span class="cls_004"> and </span><span class="cls_007">parameter</span><span class="cls_004"> input</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:108270px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background137.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">parameters, and return the </span><span class="cls_007">DependencyProperty.UnsetValue</span><span class="cls_004"> value if either are invalid. For</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">valid values, we convert both parameters to their string representations. We then create a</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_007"><span class="cls_007">bool</span><span class="cls_004"> value by comparing the two string values. Once we have our </span><span class="cls_007">bool</span><span class="cls_004"> value, we use it in</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">conjunction with the </span><span class="cls_007">IsInverted</span><span class="cls_004"> property to return the output value.</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">As with our other enumeration converter example, the </span><span class="cls_007">ConvertBack</span><span class="cls_004"> method implementation</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">is a little different again, as we are unable to return the correct enumeration instance for a</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">false value; it could be any value except the value specified by the </span><span class="cls_007">parameter</span><span class="cls_004"> input</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">parameter.</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">As such, we are only able to return the specified enumeration instance if the data bound</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">value is true and the </span><span class="cls_007">IsInverted</span><span class="cls_004"> property is false, or if it is false and the </span><span class="cls_007">IsInverted</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">property is true. For all other input values, we simply return the</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_007"><span class="cls_007">DependencyProperty.UnsetValue</span><span class="cls_004"> property, which is preferred by the property system</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">rather than the null value.</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">Let's see an example of this in use, with the </span><span class="cls_007">BitRate</span><span class="cls_004"> enumeration that we saw in the</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">previous chapter. Let's first look at the simple View Model.</span></div>
<div style="position:absolute;left:52.98px;top:279.00px" class="cls_007"><span class="cls_007">using System.Collections.ObjectModel;</span></div>
<div style="position:absolute;left:52.98px;top:292.50px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.DataModels.Enums;</span></div>
<div style="position:absolute;left:52.98px;top:306.00px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.Extensions;</span></div>
<div style="position:absolute;left:52.98px;top:333.00px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.ViewModels</span></div>
<div style="position:absolute;left:52.98px;top:346.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:360.00px" class="cls_007"><span class="cls_007">public class BitRateViewModel : BaseViewModel</span></div>
<div style="position:absolute;left:67.97px;top:373.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:387.00px" class="cls_007"><span class="cls_007">private ObservableCollection<BitRate> bitRates =</span></div>
<div style="position:absolute;left:97.96px;top:400.50px" class="cls_007"><span class="cls_007">new ObservableCollection<BitRate>();</span></div>
<div style="position:absolute;left:82.97px;top:414.00px" class="cls_007"><span class="cls_007">private BitRate bitRate = BitRate.Sixteen;</span></div>
<div style="position:absolute;left:82.97px;top:441.00px" class="cls_007"><span class="cls_007">public BitRateViewModel()</span></div>
<div style="position:absolute;left:82.97px;top:454.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:468.00px" class="cls_007"><span class="cls_007">bitRates.FillWithMembers();</span></div>
<div style="position:absolute;left:82.97px;top:481.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:508.50px" class="cls_007"><span class="cls_007">public ObservableCollection<BitRate> BitRates</span></div>
<div style="position:absolute;left:82.97px;top:522.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:535.50px" class="cls_007"><span class="cls_007">get { return bitRates; }</span></div>
<div style="position:absolute;left:97.96px;top:549.00px" class="cls_007"><span class="cls_007">set { if (bitRates != value) { bitRates = value;</span></div>
<div style="position:absolute;left:112.96px;top:562.50px" class="cls_007"><span class="cls_007">NotifyPropertyChanged(); } }</span></div>
<div style="position:absolute;left:82.97px;top:576.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:603.00px" class="cls_007"><span class="cls_007">public BitRate BitRate</span></div>
<div style="position:absolute;left:82.97px;top:616.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:630.00px" class="cls_007"><span class="cls_007">get { return bitRate; }</span></div>
<div style="position:absolute;left:97.96px;top:643.50px" class="cls_007"><span class="cls_007">set { if (bitRate != value) { bitRate = value;</span></div>
<div style="position:absolute;left:112.96px;top:657.00px" class="cls_007"><span class="cls_007">NotifyPropertyChanged(); } }</span></div>
<div style="position:absolute;left:82.97px;top:670.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:684.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:697.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:717.75px" class="cls_004"><span class="cls_004">This class just contains a collection of type </span><span class="cls_007">BitRate</span><span class="cls_004">, which will hold all possible members</span></div>
<div style="position:absolute;left:5.00px;top:735.75px" class="cls_004"><span class="cls_004">and a selection property of type </span><span class="cls_007">BitRate</span><span class="cls_004">, which we will data bind to the various</span></div>
<div style="position:absolute;left:5.00px;top:753.75px" class="cls_007"><span class="cls_007">RadioButton</span><span class="cls_004"> elements using our new converter. Note the use of the </span><span class="cls_007">FillWithMembers</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:109072px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background138.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">Extension method in the constructor. Let's first see that:</span></div>
<div style="position:absolute;left:52.98px;top:27.00px" class="cls_007"><span class="cls_007">public static void FillWithMembers<T>(this ICollection<T></span></div>
<div style="position:absolute;left:52.98px;top:40.50px" class="cls_007"><span class="cls_007">collection)</span></div>
<div style="position:absolute;left:52.98px;top:54.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:67.50px" class="cls_007"><span class="cls_007">if (typeof(T).BaseType != typeof(Enum))</span></div>
<div style="position:absolute;left:82.97px;top:81.00px" class="cls_007"><span class="cls_007">throw new ArgumentException("The FillWithMembers<T> method can</span></div>
<div style="position:absolute;left:52.98px;top:94.50px" class="cls_007"><span class="cls_007">only be</span></div>
<div style="position:absolute;left:82.97px;top:108.00px" class="cls_007"><span class="cls_007">called with an enum as the generic type.");</span></div>
<div style="position:absolute;left:67.97px;top:121.50px" class="cls_007"><span class="cls_007">collection.Clear();</span></div>
<div style="position:absolute;left:67.97px;top:135.00px" class="cls_007"><span class="cls_007">foreach (string name in Enum.GetNames(typeof(T)))</span></div>
<div style="position:absolute;left:82.97px;top:148.50px" class="cls_007"><span class="cls_007">collection.Add((T)Enum.Parse(typeof(T), name));</span></div>
<div style="position:absolute;left:52.98px;top:162.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:182.25px" class="cls_004"><span class="cls_004">In the </span><span class="cls_007">FillWithMembers</span><span class="cls_004"> Extension method, we first check that the collection that the method</span></div>
<div style="position:absolute;left:5.00px;top:200.25px" class="cls_004"><span class="cls_004">is called on is of an enumeration type and throw an </span><span class="cls_007">ArgumentException</span><span class="cls_004"> if it's not. We then</span></div>
<div style="position:absolute;left:5.00px;top:218.25px" class="cls_004"><span class="cls_004">clear the collection, in case it has any pre-existing items in it. Finally, we iterate through the</span></div>
<div style="position:absolute;left:5.00px;top:236.25px" class="cls_004"><span class="cls_004">result of the </span><span class="cls_007">Enum.GetNames</span><span class="cls_004"> method, parsing each string name to the relevant enumeration</span></div>
<div style="position:absolute;left:5.00px;top:254.25px" class="cls_004"><span class="cls_004">member and casting it to the correct type, before adding it to the collection.</span></div>
<div style="position:absolute;left:5.00px;top:272.25px" class="cls_004"><span class="cls_004">Let's now see the XAML for the View:</span></div>
<div style="position:absolute;left:52.98px;top:295.50px" class="cls_007"><span class="cls_007"><UserControl</span></div>
<div style="position:absolute;left:52.98px;top:309.00px" class="cls_007"><span class="cls_007">x:Class="CompanyName.ApplicationName.Views.BitRateView"</span></div>
<div style="position:absolute;left:67.97px;top:322.50px" class="cls_007"><span class="cls_007">xmlns="</span><A HREF="http://schemas.microsoft.com/winfx/2006/xaml/presentation"/">http://schemas.microsoft.com/winfx/2006/xaml/presentation"</A> </div>
<div style="position:absolute;left:67.97px;top:336.00px" class="cls_007"><span class="cls_007">xmlns:x="</span><A HREF="http://schemas.microsoft.com/winfx/2006/xaml"/">http://schemas.microsoft.com/winfx/2006/xaml"</A> </div>
<div style="position:absolute;left:67.97px;top:349.50px" class="cls_007"><span class="cls_007">xmlns:mc="</span><A HREF="http://schemas.openxmlformats.org/markup-/">http://schemas.openxmlformats.org/markup-</A> </div>
<div style="position:absolute;left:52.98px;top:363.00px" class="cls_007"><span class="cls_007">compatibility/2006"</span></div>
<div style="position:absolute;left:67.97px;top:376.50px" class="cls_007"><span class="cls_007">xmlns:d="</span><A HREF="http://schemas.microsoft.com/expression/blend/2008"/">http://schemas.microsoft.com/expression/blend/2008"</A> </div>
<div style="position:absolute;left:67.97px;top:390.00px" class="cls_007"><span class="cls_007">xmlns:Converters="clr-</span></div>
<div style="position:absolute;left:52.98px;top:403.50px" class="cls_007"><span class="cls_007">namespace:CompanyName.ApplicationName.Converters;</span></div>
<div style="position:absolute;left:82.97px;top:417.00px" class="cls_007"><span class="cls_007">assembly=CompanyName.ApplicationName.Converters"</span></div>
<div style="position:absolute;left:67.97px;top:430.50px" class="cls_007"><span class="cls_007">mc:Ignorable="d" d:DesignHeight="60" d:DesignWidth="300"></span></div>
<div style="position:absolute;left:67.97px;top:444.00px" class="cls_007"><span class="cls_007"><UserControl.Resources></span></div>
<div style="position:absolute;left:82.97px;top:457.50px" class="cls_007"><span class="cls_007"><Converters:EnumToBoolConverter x:Key="EnumToBoolConverter" /></span></div>
<div style="position:absolute;left:67.97px;top:471.00px" class="cls_007"><span class="cls_007"></UserControl.Resources></span></div>
<div style="position:absolute;left:67.97px;top:484.50px" class="cls_007"><span class="cls_007"><GroupBox Header="Audio Quality" HorizontalAlignment="Left"</span></div>
<div style="position:absolute;left:82.97px;top:498.00px" class="cls_007"><span class="cls_007">VerticalAlignment="Top" Padding="5"></span></div>
<div style="position:absolute;left:82.97px;top:511.50px" class="cls_007"><span class="cls_007"><StackPanel></span></div>
<div style="position:absolute;left:97.96px;top:525.00px" class="cls_007"><span class="cls_007"><RadioButton Content="16 bits" IsChecked="{Binding BitRate,</span></div>
<div style="position:absolute;left:112.96px;top:538.50px" class="cls_007"><span class="cls_007">Converter={StaticResource EnumToBoolConverter},</span></div>
<div style="position:absolute;left:112.96px;top:552.00px" class="cls_007"><span class="cls_007">ConverterParameter=Sixteen}"</span></div>
<div style="position:absolute;left:52.98px;top:565.50px" class="cls_007"><span class="cls_007">VerticalContentAlignment="Center" /></span></div>
<div style="position:absolute;left:97.96px;top:579.00px" class="cls_007"><span class="cls_007"><RadioButton Content="24 bits" IsChecked="{Binding BitRate,</span></div>
<div style="position:absolute;left:112.96px;top:592.50px" class="cls_007"><span class="cls_007">Converter={StaticResource EnumToBoolConverter},</span></div>
<div style="position:absolute;left:52.98px;top:606.00px" class="cls_007"><span class="cls_007">ConverterParameter=</span></div>
<div style="position:absolute;left:112.96px;top:619.50px" class="cls_007"><span class="cls_007">TwentyFour}" VerticalContentAlignment="Center" /></span></div>
<div style="position:absolute;left:97.96px;top:633.00px" class="cls_007"><span class="cls_007"><RadioButton Content="32 bits" IsChecked="{Binding BitRate,</span></div>
<div style="position:absolute;left:112.96px;top:646.50px" class="cls_007"><span class="cls_007">Converter={StaticResource EnumToBoolConverter},</span></div>
<div style="position:absolute;left:112.96px;top:660.00px" class="cls_007"><span class="cls_007">ConverterParameter=ThirtyTwo}"</span></div>
<div style="position:absolute;left:52.98px;top:673.50px" class="cls_007"><span class="cls_007">VerticalContentAlignment="Center" /></span></div>
<div style="position:absolute;left:82.97px;top:687.00px" class="cls_007"><span class="cls_007"></StackPanel></span></div>
<div style="position:absolute;left:67.97px;top:700.50px" class="cls_007"><span class="cls_007"></GroupBox></span></div>
<div style="position:absolute;left:52.98px;top:714.00px" class="cls_007"><span class="cls_007"></UserControl></span></div>
<div style="position:absolute;left:5.00px;top:747.00px" class="cls_004"><span class="cls_004">In this View, we setup the </span><span class="cls_007">Converters</span><span class="cls_004"> XML namespace prefix and then declare an instance</span></div>
<div style="position:absolute;left:5.00px;top:765.00px" class="cls_004"><span class="cls_004">of the </span><span class="cls_007">EnumToBoolConverter</span><span class="cls_004"> class in the </span><span class="cls_007">Resources</span><span class="cls_004"> section. We then declare a </span><span class="cls_007">StackPanel</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:109874px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background139.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">containing three </span><span class="cls_007">RadioButton</span><span class="cls_004"> elements inside a </span><span class="cls_007">GroupBox</span><span class="cls_004">. Each </span><span class="cls_007">RadioButton</span><span class="cls_004"> element is</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">data bound to the same </span><span class="cls_007">BitRate</span><span class="cls_004"> property from our View Model, using the converter from</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">the resources.</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">Each button specifies a different enumeration member in its binding's </span><span class="cls_007">ConverterParameter</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">property and this is passed through to the converter in the </span><span class="cls_007">parameter</span><span class="cls_004"> input parameter. If a</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_007"><span class="cls_007">RadioButton</span><span class="cls_004"> is checked, its true value is passed to the converter and converted to the value</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">specified by its </span><span class="cls_007">ConverterParameter</span><span class="cls_004"> value and the </span><span class="cls_007">BitRate</span><span class="cls_004"> property is updated with that</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">value. The output of this code looks like the following figure:</span></div>
<div style="position:absolute;left:5.00px;top:248.25px" class="cls_004"><span class="cls_004">Note that if we had a large number of enumeration members, or the members were</span></div>
<div style="position:absolute;left:5.00px;top:266.25px" class="cls_004"><span class="cls_004">changed regularly, declaring each one manually in the UI like this example might not be such</span></div>
<div style="position:absolute;left:5.00px;top:284.25px" class="cls_004"><span class="cls_004">a good idea. In these cases, we could generate the same UI with less work, utilizing a</span></div>
<div style="position:absolute;left:5.00px;top:302.25px" class="cls_007"><span class="cls_007">DataTemplate</span><span class="cls_004"> object. We'll see an example of this later in this chapter, but for now, let's</span></div>
<div style="position:absolute;left:5.00px;top:320.25px" class="cls_004"><span class="cls_004">return to the input parameters of our converter.</span></div>
<div style="position:absolute;left:5.00px;top:338.25px" class="cls_004"><span class="cls_004">The final input parameter in the </span><span class="cls_007">Convert</span><span class="cls_004"> and </span><span class="cls_007">ConvertBack</span><span class="cls_004"> methods is the </span><span class="cls_007">culture</span></div>
<div style="position:absolute;left:5.00px;top:356.25px" class="cls_004"><span class="cls_004">parameter of type </span><span class="cls_007">CultureInfo</span><span class="cls_004">. In non-international applications, we can simply ignore this</span></div>
<div style="position:absolute;left:5.00px;top:374.25px" class="cls_004"><span class="cls_004">parameter, however if globalization plays a part in your application, then using this</span></div>
<div style="position:absolute;left:5.00px;top:392.25px" class="cls_004"><span class="cls_004">parameter is essential.</span></div>
<div style="position:absolute;left:5.00px;top:410.25px" class="cls_004"><span class="cls_004">It enables us to correctly format any textual output that we may have in our converter using</span></div>
<div style="position:absolute;left:5.00px;top:428.25px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">object.ToString</span><span class="cls_004"> method and keep it in line with the rest of the text in the application.</span></div>
<div style="position:absolute;left:5.00px;top:446.25px" class="cls_004"><span class="cls_004">We can also use it in the various </span><span class="cls_007">Convert</span><span class="cls_004"> class methods to ensure that numerals are also</span></div>
<div style="position:absolute;left:5.00px;top:464.25px" class="cls_004"><span class="cls_004">correctly output in the right format. Globalization is beyond the scope of this book and so</span></div>
<div style="position:absolute;left:5.00px;top:482.25px" class="cls_004"><span class="cls_004">we'll move on now.</span></div>
<div style="position:absolute;left:5.00px;top:499.51px" class="cls_011"><span class="cls_011">Binding multiple sources to a single target property</span></div>
<div style="position:absolute;left:5.00px;top:529.50px" class="cls_004"><span class="cls_004">In WPF, there is another, more common way to data bind to multiple binding sources at</span></div>
<div style="position:absolute;left:5.00px;top:547.50px" class="cls_004"><span class="cls_004">once and to perform some sort of conversion from the various values to a single output</span></div>
<div style="position:absolute;left:5.00px;top:565.50px" class="cls_004"><span class="cls_004">value. In order to achieve this, we need to use a </span><span class="cls_007">MultiBinding</span><span class="cls_004"> object in conjunction with a</span></div>
<div style="position:absolute;left:5.00px;top:583.50px" class="cls_004"><span class="cls_004">class that implements the </span><span class="cls_007">IMultiValueConverter</span><span class="cls_004"> interface.</span></div>
<div style="position:absolute;left:5.00px;top:601.50px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">MultiBinding</span><span class="cls_004"> class enables us to declare multiple binding sources and a single binding</span></div>
<div style="position:absolute;left:5.00px;top:619.50px" class="cls_004"><span class="cls_004">target. If the </span><span class="cls_007">Mode</span><span class="cls_004"> or </span><span class="cls_007">UpdateSourceTrigger</span><span class="cls_004"> properties of the </span><span class="cls_007">MultiBinding</span><span class="cls_004"> class are set,</span></div>
<div style="position:absolute;left:5.00px;top:637.50px" class="cls_004"><span class="cls_004">then their values are inherited by the contained </span><span class="cls_007">binding</span><span class="cls_004"> elements, unless they have different</span></div>
<div style="position:absolute;left:5.00px;top:655.50px" class="cls_004"><span class="cls_004">values set explicitly.</span></div>
<div style="position:absolute;left:5.00px;top:673.50px" class="cls_004"><span class="cls_004">The values from the multiple binding sources can be combined in one of two ways; their</span></div>
<div style="position:absolute;left:5.00px;top:691.50px" class="cls_004"><span class="cls_004">string representations can be output using the </span><span class="cls_007">StringFormat</span><span class="cls_004"> property, or we can use a</span></div>
<div style="position:absolute;left:5.00px;top:709.50px" class="cls_004"><span class="cls_004">class that implements the </span><span class="cls_007">IMultiValueConverter</span><span class="cls_004"> interface to generate the output value.</span></div>
<div style="position:absolute;left:5.00px;top:727.50px" class="cls_004"><span class="cls_004">This interface is very similar to the </span><span class="cls_007">IValueConverter</span><span class="cls_004"> interface, but works with multiple data</span></div>
<div style="position:absolute;left:5.00px;top:745.50px" class="cls_004"><span class="cls_004">bound values instead.</span></div>
<div style="position:absolute;left:5.00px;top:763.50px" class="cls_004"><span class="cls_004">When implementing the </span><span class="cls_007">IMultiValueConverter</span><span class="cls_004"> interface, we do not set the</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:110676px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background140.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_007"><span class="cls_007">ValueConversion</span><span class="cls_004"> attribute that we are accustomed to setting in the </span><span class="cls_007">IValueConverter</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">implementations that we have created.</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">In the </span><span class="cls_007">Convert</span><span class="cls_004"> method that we need to implement, the </span><span class="cls_007">value</span><span class="cls_004"> input parameter of type</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_007"><span class="cls_007">object</span><span class="cls_004"> from the </span><span class="cls_007">IValueConverter</span><span class="cls_004"> interface is replaced by an object array named </span><span class="cls_007">values</span><span class="cls_004">,</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">which contains our input values.</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">In the </span><span class="cls_007">ConvertBack</span><span class="cls_004"> method, we have an array of type </span><span class="cls_007">Type</span><span class="cls_004"> for the types of the binding</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">targets and one of type </span><span class="cls_007">object</span><span class="cls_004"> for the return types. Apart from these slight differences,</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">these two interfaces are the same. Let's look at an example to help clarify the situation.</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">Imagine a scenario where a healthcare application needs to display a patient's weight</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">measurements over time. It would be helpful if we could output an indicator of whether each</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">consecutive measurement was higher or lower than the previous one, to highlight any</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">unhealthy trends.</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">This can be implemented using the </span><span class="cls_007">RelativeSource.PreviousData</span><span class="cls_004"> property mentioned</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">earlier, a </span><span class="cls_007">MultiBinding</span><span class="cls_004"> object and an </span><span class="cls_007">IMultiValueConverter</span><span class="cls_004"> class. Let's first take a look at</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">how we implement the </span><span class="cls_007">IMultiValueConverter</span><span class="cls_004"> interface.</span></div>
<div style="position:absolute;left:52.98px;top:279.00px" class="cls_007"><span class="cls_007">using System;</span></div>
<div style="position:absolute;left:52.98px;top:292.50px" class="cls_007"><span class="cls_007">using System.Globalization;</span></div>
<div style="position:absolute;left:52.98px;top:306.00px" class="cls_007"><span class="cls_007">using System.Windows;</span></div>
<div style="position:absolute;left:52.98px;top:319.50px" class="cls_007"><span class="cls_007">using System.Windows.Data;</span></div>
<div style="position:absolute;left:52.98px;top:346.50px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.Converters</span></div>
<div style="position:absolute;left:52.98px;top:360.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:373.50px" class="cls_007"><span class="cls_007">public class HigherLowerConverter : IMultiValueConverter</span></div>
<div style="position:absolute;left:67.97px;top:387.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:400.50px" class="cls_007"><span class="cls_007">public object Convert(object[] values, Type targetType,</span></div>
<div style="position:absolute;left:97.96px;top:414.00px" class="cls_007"><span class="cls_007">object parameter, CultureInfo culture)</span></div>
<div style="position:absolute;left:82.97px;top:427.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:441.00px" class="cls_007"><span class="cls_007">if (values == null || values.Length != 2 || values[0] == null</span></div>
<div style="position:absolute;left:52.98px;top:454.50px" class="cls_007"><span class="cls_007">||</span></div>
<div style="position:absolute;left:112.96px;top:468.00px" class="cls_007"><span class="cls_007">values[1] == null || values[0].GetType() != typeof(int) ||</span></div>
<div style="position:absolute;left:112.96px;top:481.50px" class="cls_007"><span class="cls_007">values[1].GetType() != typeof(int))</span></div>
<div style="position:absolute;left:112.96px;top:495.00px" class="cls_007"><span class="cls_007">return DependencyProperty.UnsetValue;</span></div>
<div style="position:absolute;left:97.96px;top:508.50px" class="cls_007"><span class="cls_007">int intValue = (int)values[0];</span></div>
<div style="position:absolute;left:97.96px;top:522.00px" class="cls_007"><span class="cls_007">int previousValue = (int)values[1];</span></div>
<div style="position:absolute;left:97.96px;top:535.50px" class="cls_007"><span class="cls_007">return intValue > previousValue ? "->" : "<-";</span></div>
<div style="position:absolute;left:82.97px;top:549.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:576.00px" class="cls_007"><span class="cls_007">public object[] ConvertBack(object value, Type[] targetTypes,</span></div>
<div style="position:absolute;left:97.96px;top:589.50px" class="cls_007"><span class="cls_007">object parameter, CultureInfo culture)</span></div>
<div style="position:absolute;left:82.97px;top:603.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:616.50px" class="cls_007"><span class="cls_007">return new object[2] { DependencyProperty.UnsetValue,</span></div>
<div style="position:absolute;left:112.96px;top:630.00px" class="cls_007"><span class="cls_007">DependencyProperty.UnsetValue };</span></div>
<div style="position:absolute;left:82.97px;top:643.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:657.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:670.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:703.50px" class="cls_004"><span class="cls_004">We start our implementation with the customary validation of the input values. In this</span></div>
<div style="position:absolute;left:5.00px;top:721.50px" class="cls_004"><span class="cls_004">specific converter, we are expecting two values of type </span><span class="cls_007">int</span><span class="cls_004"> and so verify that we have that</span></div>
<div style="position:absolute;left:5.00px;top:739.50px" class="cls_004"><span class="cls_004">before continuing. If valid, we cast our two values to </span><span class="cls_007">int</span><span class="cls_004"> and compare them, returning the</span></div>
<div style="position:absolute;left:5.00px;top:757.50px" class="cls_004"><span class="cls_004">appropriate string based direction arrow, dependent on the result of the comparison.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:111478px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background141.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">As the </span><span class="cls_007">ConvertBack</span><span class="cls_004"> method is not required for our example, we simply return an object</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">array that contains two </span><span class="cls_007">DependencyProperty.UnsetValue</span><span class="cls_004"> values. Let's take a quick look at</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">our View Model next.</span></div>
<div style="position:absolute;left:52.98px;top:63.00px" class="cls_007"><span class="cls_007">using System.Collections.Generic;</span></div>
<div style="position:absolute;left:52.98px;top:90.00px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.ViewModels</span></div>
<div style="position:absolute;left:52.98px;top:103.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:117.00px" class="cls_007"><span class="cls_007">public class WeightMeasurementsViewModel : BaseViewModel</span></div>
<div style="position:absolute;left:67.97px;top:130.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:144.00px" class="cls_007"><span class="cls_007">private List<int> weights =</span></div>
<div style="position:absolute;left:97.96px;top:157.50px" class="cls_007"><span class="cls_007">new List<int>() { 90, 89, 92, 91, 94, 95, 98, 99, 101 };</span></div>
<div style="position:absolute;left:82.97px;top:184.50px" class="cls_007"><span class="cls_007">public List<int> Weights</span></div>
<div style="position:absolute;left:82.97px;top:198.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:211.50px" class="cls_007"><span class="cls_007">get { return weights; }</span></div>
<div style="position:absolute;left:97.96px;top:225.00px" class="cls_007"><span class="cls_007">set { weights = value; NotifyPropertyChanged(); }</span></div>
<div style="position:absolute;left:82.97px;top:238.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:252.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:265.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:285.75px" class="cls_004"><span class="cls_004">Here, we have a very simple View Model, with just one field and property pair. We've just</span></div>
<div style="position:absolute;left:5.00px;top:303.75px" class="cls_004"><span class="cls_004">hard coded a few test values to demonstrate with. Let's now take a look at our View.</span></div>
<div style="position:absolute;left:52.98px;top:327.00px" class="cls_007"><span class="cls_007"><UserControl</span></div>
<div style="position:absolute;left:52.98px;top:354.00px" class="cls_007"><span class="cls_007">x:Class="CompanyName.ApplicationName.Views.WeightMeasurementsView"</span></div>
<div style="position:absolute;left:67.97px;top:367.50px" class="cls_007"><span class="cls_007">xmlns="</span><A HREF="http://schemas.microsoft.com/winfx/2006/xaml/presentation"/">http://schemas.microsoft.com/winfx/2006/xaml/presentation"</A> </div>
<div style="position:absolute;left:67.97px;top:381.00px" class="cls_007"><span class="cls_007">xmlns:x="</span><A HREF="http://schemas.microsoft.com/winfx/2006/xaml"/">http://schemas.microsoft.com/winfx/2006/xaml"</A> </div>
<div style="position:absolute;left:67.97px;top:394.50px" class="cls_007"><span class="cls_007">xmlns:mc="</span><A HREF="http://schemas.openxmlformats.org/markup-/">http://schemas.openxmlformats.org/markup-</A> </div>
<div style="position:absolute;left:52.98px;top:408.00px" class="cls_007"><span class="cls_007">compatibility/2006"</span></div>
<div style="position:absolute;left:67.97px;top:421.50px" class="cls_007"><span class="cls_007">xmlns:d="</span><A HREF="http://schemas.microsoft.com/expression/blend/2008"/">http://schemas.microsoft.com/expression/blend/2008"</A> </div>
<div style="position:absolute;left:67.97px;top:435.00px" class="cls_007"><span class="cls_007">xmlns:Converters="clr-</span></div>
<div style="position:absolute;left:52.98px;top:448.50px" class="cls_007"><span class="cls_007">namespace:CompanyName.ApplicationName.Converters;</span></div>
<div style="position:absolute;left:82.97px;top:462.00px" class="cls_007"><span class="cls_007">assembly=CompanyName.ApplicationName.Converters"</span></div>
<div style="position:absolute;left:67.97px;top:475.50px" class="cls_007"><span class="cls_007">xmlns:System="clr-namespace:System;assembly=mscorlib"</span></div>
<div style="position:absolute;left:67.97px;top:489.00px" class="cls_007"><span class="cls_007">mc:Ignorable="d" d:DesignHeight="90" d:DesignWidth="300"></span></div>
<div style="position:absolute;left:67.97px;top:502.50px" class="cls_007"><span class="cls_007"><UserControl.Resources></span></div>
<div style="position:absolute;left:82.97px;top:516.00px" class="cls_007"><span class="cls_007"><Converters:HigherLowerConverter x:Key="HigherLowerConverter"</span></div>
<div style="position:absolute;left:52.98px;top:529.50px" class="cls_007"><span class="cls_007">/></span></div>
<div style="position:absolute;left:67.97px;top:543.00px" class="cls_007"><span class="cls_007"></UserControl.Resources></span></div>
<div style="position:absolute;left:67.97px;top:556.50px" class="cls_007"><span class="cls_007"><Border BorderBrush="Black" BorderThickness="1" CornerRadius="5"</span></div>
<div style="position:absolute;left:82.97px;top:570.00px" class="cls_007"><span class="cls_007">HorizontalAlignment="Left" VerticalAlignment="Top"></span></div>
<div style="position:absolute;left:82.97px;top:583.50px" class="cls_007"><span class="cls_007"><ItemsControl ItemsSource="{Binding Weights}"</span></div>
<div style="position:absolute;left:52.98px;top:597.00px" class="cls_007"><span class="cls_007">Margin="20,20,0,20"></span></div>
<div style="position:absolute;left:97.96px;top:610.50px" class="cls_007"><span class="cls_007"><ItemsControl.ItemsPanel></span></div>
<div style="position:absolute;left:112.96px;top:624.00px" class="cls_007"><span class="cls_007"><ItemsPanelTemplate></span></div>
<div style="position:absolute;left:127.95px;top:637.50px" class="cls_007"><span class="cls_007"><StackPanel Orientation="Horizontal" /></span></div>
<div style="position:absolute;left:112.96px;top:651.00px" class="cls_007"><span class="cls_007"></ItemsPanelTemplate></span></div>
<div style="position:absolute;left:97.96px;top:664.50px" class="cls_007"><span class="cls_007"></ItemsControl.ItemsPanel></span></div>
<div style="position:absolute;left:97.96px;top:678.00px" class="cls_007"><span class="cls_007"><ItemsControl.ItemTemplate></span></div>
<div style="position:absolute;left:112.96px;top:691.50px" class="cls_007"><span class="cls_007"><DataTemplate DataType="{x:Type System:Int32}"></span></div>
<div style="position:absolute;left:127.95px;top:705.00px" class="cls_007"><span class="cls_007"><StackPanel Margin="0,0,20,0"></span></div>
<div style="position:absolute;left:142.94px;top:718.50px" class="cls_007"><span class="cls_007"><TextBlock Text="{Binding}" /></span></div>
<div style="position:absolute;left:142.94px;top:732.00px" class="cls_007"><span class="cls_007"><TextBlock HorizontalAlignment="Center"></span></div>
<div style="position:absolute;left:157.94px;top:745.50px" class="cls_007"><span class="cls_007"><TextBlock.Text></span></div>
<div style="position:absolute;left:172.93px;top:759.00px" class="cls_007"><span class="cls_007"><MultiBinding</span></div>
<div style="position:absolute;left:187.92px;top:772.50px" class="cls_007"><span class="cls_007">Converter="{StaticResource</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:112280px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background142.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:3.00px" class="cls_007"><span class="cls_007">HigherLowerConverter}"></span></div>
<div style="position:absolute;left:187.92px;top:16.50px" class="cls_007"><span class="cls_007"><Binding /></span></div>
<div style="position:absolute;left:187.92px;top:30.00px" class="cls_007"><span class="cls_007"><Binding</span></div>
<div style="position:absolute;left:202.92px;top:43.50px" class="cls_007"><span class="cls_007">RelativeSource="{RelativeSource PreviousData}"</span></div>
<div style="position:absolute;left:52.98px;top:57.00px" class="cls_007"><span class="cls_007">/></span></div>
<div style="position:absolute;left:172.93px;top:70.50px" class="cls_007"><span class="cls_007"></MultiBinding></span></div>
<div style="position:absolute;left:157.94px;top:84.00px" class="cls_007"><span class="cls_007"></TextBlock.Text></span></div>
<div style="position:absolute;left:142.94px;top:97.50px" class="cls_007"><span class="cls_007"></TextBlock></span></div>
<div style="position:absolute;left:127.95px;top:111.00px" class="cls_007"><span class="cls_007"></StackPanel></span></div>
<div style="position:absolute;left:112.96px;top:124.50px" class="cls_007"><span class="cls_007"></DataTemplate></span></div>
<div style="position:absolute;left:97.96px;top:138.00px" class="cls_007"><span class="cls_007"></ItemsControl.ItemTemplate></span></div>
<div style="position:absolute;left:82.97px;top:151.50px" class="cls_007"><span class="cls_007"></ItemsControl></span></div>
<div style="position:absolute;left:67.97px;top:165.00px" class="cls_007"><span class="cls_007"></Border></span></div>
<div style="position:absolute;left:52.98px;top:178.50px" class="cls_007"><span class="cls_007"></UserControl></span></div>
<div style="position:absolute;left:5.00px;top:211.50px" class="cls_004"><span class="cls_004">After the </span><span class="cls_007">Converters</span><span class="cls_004"> XML namespace prefix and the declared </span><span class="cls_007">HigherLowerConverter</span></div>
<div style="position:absolute;left:5.00px;top:229.50px" class="cls_004"><span class="cls_004">element in the </span><span class="cls_007">Resources</span><span class="cls_004"> section, we have a bordered </span><span class="cls_007">ItemsControl</span><span class="cls_004"> that is data bound to</span></div>
<div style="position:absolute;left:5.00px;top:247.50px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">Weights</span><span class="cls_004"> property of the View Model that is set as the </span><span class="cls_007">DataContext</span><span class="cls_004"> of this View. Next,</span></div>
<div style="position:absolute;left:5.00px;top:265.50px" class="cls_004"><span class="cls_004">we see a horizontal </span><span class="cls_007">StackPanel</span><span class="cls_004"> element being used as the </span><span class="cls_007">ItemsPanelTemplate</span><span class="cls_004"> in the</span></div>
<div style="position:absolute;left:5.00px;top:283.50px" class="cls_007"><span class="cls_007">ItemsControl.ItemsPanel</span><span class="cls_004"> property. This simply makes the collection control display items</span></div>
<div style="position:absolute;left:5.00px;top:301.50px" class="cls_004"><span class="cls_004">horizontally instead of vertically.</span></div>
<div style="position:absolute;left:5.00px;top:319.50px" class="cls_004"><span class="cls_004">Note that in the following </span><span class="cls_007">DataTemplate</span><span class="cls_004"> object, we need to specify the data type and so</span></div>
<div style="position:absolute;left:5.00px;top:337.50px" class="cls_004"><span class="cls_004">need to import the </span><span class="cls_007">System</span><span class="cls_004"> namespace from the </span><span class="cls_007">mscorlib</span><span class="cls_004"> assembly to reference the </span><span class="cls_007">Int32</span></div>
<div style="position:absolute;left:5.00px;top:355.50px" class="cls_004"><span class="cls_004">type. The binding to the </span><span class="cls_007">Text</span><span class="cls_004"> property in the first </span><span class="cls_007">TextBlock</span><span class="cls_004"> specifies that it is binding to the</span></div>
<div style="position:absolute;left:5.00px;top:373.50px" class="cls_004"><span class="cls_004">whole data source object, which is simply an integer in this case.</span></div>
<div style="position:absolute;left:5.00px;top:391.50px" class="cls_004"><span class="cls_004">The binding to the </span><span class="cls_007">Text</span><span class="cls_004"> property in the second </span><span class="cls_007">TextBlock</span><span class="cls_004"> is where we are using our</span></div>
<div style="position:absolute;left:5.00px;top:409.50px" class="cls_007"><span class="cls_007">MultiBinding</span><span class="cls_004"> and </span><span class="cls_007">IMultiValueConverter</span><span class="cls_004"> elements. We set our </span><span class="cls_007">HigherLowerConverter</span></div>
<div style="position:absolute;left:5.00px;top:427.50px" class="cls_004"><span class="cls_004">class to the </span><span class="cls_007">Converter</span><span class="cls_004"> property of the </span><span class="cls_007">MultiBinding</span><span class="cls_004"> object and inside this, we specify two</span></div>
<div style="position:absolute;left:5.00px;top:445.50px" class="cls_004"><span class="cls_004">binding objects. The first is again binding to the integer value and the second uses the</span></div>
<div style="position:absolute;left:5.00px;top:463.50px" class="cls_007"><span class="cls_007">RelativeSource.PreviousData</span><span class="cls_004"> property to data bind to the previous integer value. Let's</span></div>
<div style="position:absolute;left:5.00px;top:481.50px" class="cls_004"><span class="cls_004">now see the output of this example:</span></div>
<div style="position:absolute;left:5.00px;top:601.50px" class="cls_004"><span class="cls_004">Each value after the first have an arrow displayed underneath, that specifies whether it is</span></div>
<div style="position:absolute;left:5.00px;top:619.50px" class="cls_004"><span class="cls_004">higher or lower than the previous value. While the visual output of this example could be</span></div>
<div style="position:absolute;left:5.00px;top:637.50px" class="cls_004"><span class="cls_004">improved, it does still highlight the worrying trend of the weight measurements continually</span></div>
<div style="position:absolute;left:5.00px;top:655.50px" class="cls_004"><span class="cls_004">increasing towards the end of the sample data. This useful technique can be used in any</span></div>
<div style="position:absolute;left:5.00px;top:673.50px" class="cls_004"><span class="cls_004">situation when we need to compare current data values with previous values, such as when</span></div>
<div style="position:absolute;left:5.00px;top:691.50px" class="cls_004"><span class="cls_004">displaying share prices, or stock levels.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:113082px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background143.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_008"><span class="cls_008">Dependency Properties</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">We've already seen some examples of Dependency Properties in previous chapters, but</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">now let's take a more thorough look. We have a large number of options that we can use</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">when declaring these properties, some more commonly used than others. Let's investigate</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">the standard declaration first, by defining an </span><span class="cls_007">Hours</span><span class="cls_004"> property of type </span><span class="cls_007">int</span><span class="cls_004"> in a class named</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_007"><span class="cls_007">DurationPicker</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:52.98px;top:135.00px" class="cls_007"><span class="cls_007">public static readonly DependencyProperty HoursProperty =</span></div>
<div style="position:absolute;left:67.97px;top:148.50px" class="cls_007"><span class="cls_007">DependencyProperty.Register(nameof(Hours), typeof(int),</span></div>
<div style="position:absolute;left:67.97px;top:162.00px" class="cls_007"><span class="cls_007">typeof(DurationPicker));</span></div>
<div style="position:absolute;left:52.98px;top:189.00px" class="cls_007"><span class="cls_007">public int Hours</span></div>
<div style="position:absolute;left:52.98px;top:202.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:216.00px" class="cls_007"><span class="cls_007">get { return (int)GetValue(HoursProperty); }</span></div>
<div style="position:absolute;left:67.97px;top:229.50px" class="cls_007"><span class="cls_007">set { SetValue(HoursProperty, value); }</span></div>
<div style="position:absolute;left:52.98px;top:243.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:263.25px" class="cls_004"><span class="cls_004">As with all Dependency Properties, we start by declaring the property as </span><span class="cls_007">static</span><span class="cls_004"> and</span></div>
<div style="position:absolute;left:5.00px;top:281.25px" class="cls_007"><span class="cls_007">readonly</span><span class="cls_004">, because we only want a single, immutable instance of it. This also enables us to</span></div>
<div style="position:absolute;left:5.00px;top:299.25px" class="cls_004"><span class="cls_004">access it without an instance of our class.</span></div>
<div style="position:absolute;left:5.00px;top:317.25px" class="cls_004"><span class="cls_004">Note that this </span><span class="cls_007">readonly</span><span class="cls_004"> declaration does </span><span class="cls_006">not</span><span class="cls_004"> mean that we cannot set the value of our</span></div>
<div style="position:absolute;left:5.00px;top:336.00px" class="cls_004"><span class="cls_004">property. Unlike normal CLR properties, we do not store the values of our Dependency</span></div>
<div style="position:absolute;left:5.00px;top:354.00px" class="cls_004"><span class="cls_004">Properties in a field that backs the property.</span></div>
<div style="position:absolute;left:5.00px;top:372.00px" class="cls_004"><span class="cls_004">Instead, they are stored in a separate dictionary and our declared </span><span class="cls_007">DependencyProperty</span></div>
<div style="position:absolute;left:5.00px;top:390.00px" class="cls_004"><span class="cls_004">here is merely the identifier that is used to access the values from that dictionary. This is the</span></div>
<div style="position:absolute;left:5.00px;top:408.00px" class="cls_004"><span class="cls_004">reason that we need to dynamically get and set the actual values using the </span><span class="cls_007">GetValue</span><span class="cls_004"> and</span></div>
<div style="position:absolute;left:5.00px;top:426.00px" class="cls_007"><span class="cls_007">SetValue</span><span class="cls_004"> methods, passing the property.</span></div>
<div style="position:absolute;left:5.00px;top:444.00px" class="cls_004"><span class="cls_004">The result of this arrangement is that it saves a huge amount of memory, because only</span></div>
<div style="position:absolute;left:5.00px;top:462.00px" class="cls_004"><span class="cls_004">Dependency Property values that have been explicitly set will be stored in the dictionary,</span></div>
<div style="position:absolute;left:5.00px;top:480.00px" class="cls_004"><span class="cls_004">while default values are read from the declared Dependency Properties instead.</span></div>
<div style="position:absolute;left:5.00px;top:498.00px" class="cls_004"><span class="cls_004">To declare each property and create our key to the dictionary, we use the </span><span class="cls_007">Register</span><span class="cls_004"> method</span></div>
<div style="position:absolute;left:5.00px;top:516.00px" class="cls_004"><span class="cls_004">of the </span><span class="cls_007">DependencyProperty</span><span class="cls_004"> class. This method has a number of overloads, but all of them</span></div>
<div style="position:absolute;left:5.00px;top:534.00px" class="cls_004"><span class="cls_004">require the following information; the name and type of the property and the type of the</span></div>
<div style="position:absolute;left:5.00px;top:552.00px" class="cls_004"><span class="cls_004">declaring class, or </span><span class="cls_006">owner type</span><span class="cls_004"> as Microsoft prefer to call it.</span></div>
<div style="position:absolute;left:5.00px;top:570.75px" class="cls_004"><span class="cls_004">The overloaded methods both have an additional input parameter of type</span></div>
<div style="position:absolute;left:5.00px;top:588.75px" class="cls_007"><span class="cls_007">PropertyMetadata</span><span class="cls_004">. We'll return to this shortly, but for now let's focus on the last overload</span></div>
<div style="position:absolute;left:5.00px;top:606.75px" class="cls_004"><span class="cls_004">that also enables us to attach a </span><span class="cls_007">ValidateValueCallback</span><span class="cls_004"> handler to our property.</span></div>
<div style="position:absolute;left:5.00px;top:624.75px" class="cls_004"><span class="cls_004">As the name suggests, this is solely used for validation purposes and we cannot alter the</span></div>
<div style="position:absolute;left:5.00px;top:642.75px" class="cls_004"><span class="cls_004">data bound value in this method. Instead, we are simply required to return true or false to</span></div>
<div style="position:absolute;left:5.00px;top:660.75px" class="cls_004"><span class="cls_004">specify the validity of the current value. Let's see how we can attach this handler to our</span></div>
<div style="position:absolute;left:5.00px;top:678.75px" class="cls_004"><span class="cls_004">property and what its method signature is.</span></div>
<div style="position:absolute;left:52.98px;top:702.00px" class="cls_007"><span class="cls_007">public static readonly DependencyProperty HoursProperty =</span></div>
<div style="position:absolute;left:67.97px;top:715.50px" class="cls_007"><span class="cls_007">DependencyProperty.Register(nameof(Hours), typeof(int),</span></div>
<div style="position:absolute;left:67.97px;top:729.00px" class="cls_007"><span class="cls_007">typeof(DurationPicker), new PropertyMetadata(12),</span></div>
<div style="position:absolute;left:52.98px;top:742.50px" class="cls_007"><span class="cls_007">ValidateHours));</span></div>
<div style="position:absolute;left:52.98px;top:769.50px" class="cls_007"><span class="cls_007">private static bool ValidateHours(object value)</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:113884px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background144.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:3.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:16.50px" class="cls_007"><span class="cls_007">int intValue = (int)value;</span></div>
<div style="position:absolute;left:67.97px;top:30.00px" class="cls_007"><span class="cls_007">return intValue > 0 && intValue < 25;</span></div>
<div style="position:absolute;left:52.98px;top:43.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:63.75px" class="cls_004"><span class="cls_004">Note that the </span><span class="cls_007">ValidateValueCallback</span><span class="cls_004"> delegate does not provide us with any reference to</span></div>
<div style="position:absolute;left:5.00px;top:81.75px" class="cls_004"><span class="cls_004">our class and so, we cannot access its other properties from this static context. In order to</span></div>
<div style="position:absolute;left:5.00px;top:99.75px" class="cls_004"><span class="cls_004">compare the current value with other property values, or to ensure that certain conditions</span></div>
<div style="position:absolute;left:5.00px;top:117.75px" class="cls_004"><span class="cls_004">are met, we can use another overload of the </span><span class="cls_007">PropertyMetadata</span><span class="cls_004"> input parameter of the</span></div>
<div style="position:absolute;left:5.00px;top:135.75px" class="cls_007"><span class="cls_007">DependencyProperty.Register</span><span class="cls_004"> method. Let's now return to focus on the </span><span class="cls_007">PropertyMetadata</span></div>
<div style="position:absolute;left:5.00px;top:153.75px" class="cls_004"><span class="cls_004">input parameter.</span></div>
<div style="position:absolute;left:5.00px;top:171.01px" class="cls_011"><span class="cls_011">Setting metadata</span></div>
<div style="position:absolute;left:5.00px;top:201.00px" class="cls_004"><span class="cls_004">Using the overloads of the </span><span class="cls_007">PropertyMetadata</span><span class="cls_004"> constructor, we can optionally set a default</span></div>
<div style="position:absolute;left:5.00px;top:219.00px" class="cls_004"><span class="cls_004">value for the property and attach handlers to be called when the value changes, or when it</span></div>
<div style="position:absolute;left:5.00px;top:237.00px" class="cls_004"><span class="cls_004">is being re-evaluated. Let's update our example to attach a </span><span class="cls_007">PropertyChangedCallback</span></div>
<div style="position:absolute;left:5.00px;top:255.00px" class="cls_004"><span class="cls_004">handler now.</span></div>
<div style="position:absolute;left:52.98px;top:278.25px" class="cls_007"><span class="cls_007">public static readonly DependencyProperty HoursProperty =</span></div>
<div style="position:absolute;left:67.97px;top:291.75px" class="cls_007"><span class="cls_007">DependencyProperty.Register(nameof(Hours), typeof(int),</span></div>
<div style="position:absolute;left:67.97px;top:305.25px" class="cls_007"><span class="cls_007">typeof(DurationPicker), new PropertyMetadata(OnHoursChanged));</span></div>
<div style="position:absolute;left:52.98px;top:332.25px" class="cls_007"><span class="cls_007">private static void OnHoursChanged(DependencyObject</span></div>
<div style="position:absolute;left:52.98px;top:345.75px" class="cls_007"><span class="cls_007">dependencyObject,</span></div>
<div style="position:absolute;left:67.97px;top:359.25px" class="cls_007"><span class="cls_007">DependencyPropertyChangedEventArgs e)</span></div>
<div style="position:absolute;left:52.98px;top:372.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:386.25px" class="cls_007"><span class="cls_007">// This is the signature of PropertyChangedCallback handlers</span></div>
<div style="position:absolute;left:52.98px;top:399.75px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:420.00px" class="cls_004"><span class="cls_004">Note that our </span><span class="cls_007">PropertyChangedCallback</span><span class="cls_004"> handler must also be declared as static in order to</span></div>
<div style="position:absolute;left:5.00px;top:438.00px" class="cls_004"><span class="cls_004">be used from the static context of the declared </span><span class="cls_007">DependencyProperty</span><span class="cls_004"> as shown in the</span></div>
<div style="position:absolute;left:5.00px;top:456.00px" class="cls_004"><span class="cls_004">preceding code. However, we may have a situation where we need to call an instance</span></div>
<div style="position:absolute;left:5.00px;top:474.00px" class="cls_004"><span class="cls_004">method rather than a static method and in these cases, we can declare an anonymous</span></div>
<div style="position:absolute;left:5.00px;top:492.00px" class="cls_004"><span class="cls_004">method that calls our instance method like this.</span></div>
<div style="position:absolute;left:52.98px;top:515.25px" class="cls_007"><span class="cls_007">public static readonly DependencyProperty HoursProperty =</span></div>
<div style="position:absolute;left:67.97px;top:528.75px" class="cls_007"><span class="cls_007">DependencyProperty.Register(nameof(Hours),</span></div>
<div style="position:absolute;left:67.97px;top:542.25px" class="cls_007"><span class="cls_007">typeof(int), typeof(DurationPicker),</span></div>
<div style="position:absolute;left:67.97px;top:555.75px" class="cls_007"><span class="cls_007">new PropertyMetadata((d, e) =></span></div>
<div style="position:absolute;left:52.98px;top:569.25px" class="cls_007"><span class="cls_007">((DurationPicker)d).OnHoursChanged(d,e)));</span></div>
<div style="position:absolute;left:52.98px;top:596.25px" class="cls_007"><span class="cls_007">private void OnHoursChanged(DependencyObject dependencyObject,</span></div>
<div style="position:absolute;left:67.97px;top:609.75px" class="cls_007"><span class="cls_007">DependencyPropertyChangedEventArgs e)</span></div>
<div style="position:absolute;left:52.98px;top:623.25px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:636.75px" class="cls_007"><span class="cls_007">// This is the signature of non-static PropertyChangedCallback</span></div>
<div style="position:absolute;left:52.98px;top:650.25px" class="cls_007"><span class="cls_007">handlers</span></div>
<div style="position:absolute;left:52.98px;top:663.75px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:684.00px" class="cls_004"><span class="cls_004">Anonymous methods comprised of Lambda expressions can appear confusing, so let's first</span></div>
<div style="position:absolute;left:5.00px;top:702.00px" class="cls_004"><span class="cls_004">extract the relevant code.</span></div>
<div style="position:absolute;left:52.98px;top:725.25px" class="cls_007"><span class="cls_007">(d, e) => ((DurationPicker)d).OnHoursChanged(d, e))</span></div>
<div style="position:absolute;left:5.00px;top:745.50px" class="cls_004"><span class="cls_004">This could be re-written to make the example somewhat clearer.</span></div>
<div style="position:absolute;left:52.98px;top:768.75px" class="cls_007"><span class="cls_007">(DependencyObject dependencyObject,</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:114686px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background145.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:3.00px" class="cls_007"><span class="cls_007">DependencyPropertyChangedEventArgs e)</span></div>
<div style="position:absolute;left:67.97px;top:16.50px" class="cls_007"><span class="cls_007">=></span></div>
<div style="position:absolute;left:52.98px;top:43.50px" class="cls_007"><span class="cls_007">((DurationPicker)dependencyObject).OnHoursChanged(dependencyObject,</span></div>
<div style="position:absolute;left:52.98px;top:57.00px" class="cls_007"><span class="cls_007">e))</span></div>
<div style="position:absolute;left:5.00px;top:77.25px" class="cls_004"><span class="cls_004">Now we can clearly see the input parameters of the </span><span class="cls_007">PropertyChangedCallback</span><span class="cls_004"> handler,</span></div>
<div style="position:absolute;left:5.00px;top:95.25px" class="cls_004"><span class="cls_004">followed by the anonymous method body. Inside this method, we simply cast the</span></div>
<div style="position:absolute;left:5.00px;top:113.25px" class="cls_007"><span class="cls_007">dependencyObject</span><span class="cls_004"> input parameter to the type of the declaring class and then call the non-</span></div>
<div style="position:absolute;left:5.00px;top:131.25px" class="cls_004"><span class="cls_004">static method from the cast instance of the class, passing the input parameters through, if</span></div>
<div style="position:absolute;left:5.00px;top:149.25px" class="cls_004"><span class="cls_004">required.</span></div>
<div style="position:absolute;left:5.00px;top:167.25px" class="cls_004"><span class="cls_004">As we saw in the </span><span class="cls_015">Chapter 2</span><span class="cls_004">, </span><span class="cls_006">Debugging WPF Applications</span><span class="cls_004">, the CLR properties that provide</span></div>
<div style="position:absolute;left:5.00px;top:186.00px" class="cls_004"><span class="cls_004">convenient access to our Dependency Properties will not be called by the WPF Framework</span></div>
<div style="position:absolute;left:5.00px;top:204.00px" class="cls_004"><span class="cls_004">when their values change. Using this </span><span class="cls_007">PropertyChangedCallback</span><span class="cls_004"> handler is how we are able</span></div>
<div style="position:absolute;left:5.00px;top:222.00px" class="cls_004"><span class="cls_004">to perform actions upon value changes, or to debug the changing values.</span></div>
<div style="position:absolute;left:5.00px;top:240.00px" class="cls_004"><span class="cls_004">The last overload of the </span><span class="cls_007">PropertyMetadata</span><span class="cls_004"> constructor additionally enables us to provide a</span></div>
<div style="position:absolute;left:5.00px;top:258.00px" class="cls_007"><span class="cls_007">CoerceValueCallback</span><span class="cls_004"> handler, which provides the platform for us to perform any custom</span></div>
<div style="position:absolute;left:5.00px;top:276.00px" class="cls_004"><span class="cls_004">data validation that we may require for our properties. Unlike the </span><span class="cls_007">PropertyChangedCallback</span></div>
<div style="position:absolute;left:5.00px;top:294.00px" class="cls_004"><span class="cls_004">delegate, it requires us to return the output value of the property, so this enables us to</span></div>
<div style="position:absolute;left:5.00px;top:312.00px" class="cls_004"><span class="cls_004">tweak the value before returning it. Here is a simple example that shows how we can adjust</span></div>
<div style="position:absolute;left:5.00px;top:330.00px" class="cls_004"><span class="cls_004">our property values.</span></div>
<div style="position:absolute;left:52.98px;top:353.25px" class="cls_007"><span class="cls_007">public static readonly DependencyProperty HoursProperty =</span></div>
<div style="position:absolute;left:67.97px;top:366.75px" class="cls_007"><span class="cls_007">DependencyProperty.Register(nameof(Hours),</span></div>
<div style="position:absolute;left:67.97px;top:380.25px" class="cls_007"><span class="cls_007">typeof(int), typeof(DurationPicker),</span></div>
<div style="position:absolute;left:67.97px;top:393.75px" class="cls_007"><span class="cls_007">new PropertyMetadata(0, OnHoursChanged, CoerceHoursValue));</span></div>
<div style="position:absolute;left:52.98px;top:474.75px" class="cls_007"><span class="cls_007">private static object CoerceHoursValue(DependencyObject</span></div>
<div style="position:absolute;left:52.98px;top:488.25px" class="cls_007"><span class="cls_007">dependencyObject,</span></div>
<div style="position:absolute;left:67.97px;top:501.75px" class="cls_007"><span class="cls_007">object value)</span></div>
<div style="position:absolute;left:52.98px;top:515.25px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:528.75px" class="cls_007"><span class="cls_007">// Access the instance of our class from the dependencyObject</span></div>
<div style="position:absolute;left:52.98px;top:542.25px" class="cls_007"><span class="cls_007">parameter</span></div>
<div style="position:absolute;left:67.97px;top:555.75px" class="cls_007"><span class="cls_007">DurationPicker durationPicker = (DurationPicker)dependencyObject;</span></div>
<div style="position:absolute;left:67.97px;top:569.25px" class="cls_007"><span class="cls_007">int minimumValue = 1, maximumValue = durationPicker.MaximumValue;</span></div>
<div style="position:absolute;left:67.97px;top:582.75px" class="cls_007"><span class="cls_007">int actualValue = (int)value;</span></div>
<div style="position:absolute;left:67.97px;top:596.25px" class="cls_007"><span class="cls_007">return Math.Min(maximumValue, Math.Max(minimumValue,</span></div>
<div style="position:absolute;left:52.98px;top:609.75px" class="cls_007"><span class="cls_007">actualValue));</span></div>
<div style="position:absolute;left:52.98px;top:623.25px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:656.25px" class="cls_004"><span class="cls_004">In this simple example, we first cast the </span><span class="cls_007">dependencyObject</span><span class="cls_004"> input parameter, so that we can</span></div>
<div style="position:absolute;left:5.00px;top:674.25px" class="cls_004"><span class="cls_004">access its </span><span class="cls_007">MaximumValue</span><span class="cls_004"> property. Let's assume that our </span><span class="cls_007">DurationPicker</span><span class="cls_004"> control can work</span></div>
<div style="position:absolute;left:5.00px;top:692.25px" class="cls_004"><span class="cls_004">with either twelve or twenty-four hour time formats and so we need to determine the current</span></div>
<div style="position:absolute;left:5.00px;top:710.25px" class="cls_004"><span class="cls_004">upper hour limit. We can therefore constrain our </span><span class="cls_007">Hours</span><span class="cls_004"> property value to be between one</span></div>
<div style="position:absolute;left:5.00px;top:728.25px" class="cls_004"><span class="cls_004">and this upper limit.</span></div>
<div style="position:absolute;left:5.00px;top:746.25px" class="cls_004"><span class="cls_004">When using the </span><span class="cls_007">CoerceValueCallback</span><span class="cls_004"> handler, there is a special case that enables us to</span></div>
<div style="position:absolute;left:5.00px;top:764.25px" class="cls_004"><span class="cls_004">effectively cancel a change in value. If your code detects what your requirements specify to</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:115488px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background146.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">be a wholly invalid value, then you can simply return the </span><span class="cls_007">DependencyProperty.UnsetValue</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">value from the handler.</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">This value signals to the property system that it should discard the current change and</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">return the previous value instead. You could even use this technique to selectively block</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">changes to a property until a certain condition is met elsewhere in the class, for example.</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">That sums up the useful, but fairly limited options that we have with our </span><span class="cls_007">PropertyMetadata</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">object, although it should be noted that there are a number of classes that derive from this</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">class that we can use in its place and each have their own benefits. The</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_007"><span class="cls_007">UIPropertyMetadata</span><span class="cls_004"> class directly extends the </span><span class="cls_007">PropertyMetadata</span><span class="cls_004"> class and adds the ability</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">to disable all animations of the property value via its </span><span class="cls_007">IsAnimationProhibited</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">Additionally, the </span><span class="cls_007">FrameworkPropertyMetadata</span><span class="cls_004"> class further extends the </span><span class="cls_007">UIPropertyMetadata</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">class and provides us with the ability to set property inheritance, the default </span><span class="cls_007">Binding.Mode</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">and </span><span class="cls_007">Binding.UpdateSourceTrigger</span><span class="cls_004"> values of the property and a variety of</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_007"><span class="cls_007">FrameworkPropertyMetadataOptions</span><span class="cls_004"> flags that affect layout.</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">Let's take a look at some of the </span><span class="cls_007">FrameworkPropertyMetadataOptions</span><span class="cls_004"> members. If we think</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">that most users will want to use Two-Way data binding with our property, then we can</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">declare it with the </span><span class="cls_007">BindsTwoWayByDefault</span><span class="cls_004"> instance. This has the effect of switching the</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_007"><span class="cls_007">Binding.Mode</span><span class="cls_004"> from the default </span><span class="cls_007">OneWay</span><span class="cls_004"> member to the </span><span class="cls_007">TwoWay</span><span class="cls_004"> member on all bindings to our</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_004"><span class="cls_004">property.</span></div>
<div style="position:absolute;left:52.98px;top:351.00px" class="cls_007"><span class="cls_007">public static readonly DependencyProperty HoursProperty =</span></div>
<div style="position:absolute;left:67.97px;top:364.50px" class="cls_007"><span class="cls_007">DependencyProperty.Register(nameof(Hours), typeof(int),</span></div>
<div style="position:absolute;left:67.97px;top:378.00px" class="cls_007"><span class="cls_007">typeof(DurationPicker), new FrameworkPropertyMetadata(0,</span></div>
<div style="position:absolute;left:67.97px;top:391.50px" class="cls_007"><span class="cls_007">FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,</span></div>
<div style="position:absolute;left:52.98px;top:405.00px" class="cls_007"><span class="cls_007">OnHoursChanged,</span></div>
<div style="position:absolute;left:67.97px;top:418.50px" class="cls_007"><span class="cls_007">CoerceHoursValue));</span></div>
<div style="position:absolute;left:5.00px;top:438.75px" class="cls_004"><span class="cls_004">Another commonly used flag is the </span><span class="cls_007">Inherits</span><span class="cls_004"> instance, that specifies that the property value</span></div>
<div style="position:absolute;left:5.00px;top:456.75px" class="cls_004"><span class="cls_004">can be inherited by child elements. Think of the </span><span class="cls_007">FontSize</span><span class="cls_004"> or </span><span class="cls_007">Foreground</span><span class="cls_004"> properties that can</span></div>
<div style="position:absolute;left:5.00px;top:474.75px" class="cls_004"><span class="cls_004">be set on a </span><span class="cls_007">Window</span><span class="cls_004"> and inherited by each control inside it.</span></div>
<div style="position:absolute;left:5.00px;top:492.75px" class="cls_004"><span class="cls_004">Note that if we want to create a Dependency Property using this </span><span class="cls_007">Inherits</span><span class="cls_004"> member, then</span></div>
<div style="position:absolute;left:5.00px;top:510.75px" class="cls_004"><span class="cls_004">we should declare it as an Attached Property, as property value inheritance works better</span></div>
<div style="position:absolute;left:5.00px;top:528.75px" class="cls_004"><span class="cls_004">with Attached Properties. We will find out more about this soon, in a subsequent section,</span></div>
<div style="position:absolute;left:5.00px;top:546.75px" class="cls_004"><span class="cls_004">but now let's continue. Next is the </span><span class="cls_007">SubPropertiesDoNotAffectRender</span><span class="cls_004"> member, which can be</span></div>
<div style="position:absolute;left:5.00px;top:564.75px" class="cls_004"><span class="cls_004">used to streamline performance, and we'll find out more about this particular instance in</span></div>
<div style="position:absolute;left:5.00px;top:582.75px" class="cls_015"><span class="cls_015">Chapter 11</span><span class="cls_004">, </span><span class="cls_006">Deploying Your Masterpiece Application</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:601.50px" class="cls_004"><span class="cls_004">The last commonly used options are the </span><span class="cls_007">AffectsArrange</span><span class="cls_004">, </span><span class="cls_007">AffectsMeasure</span><span class="cls_004">,</span></div>
<div style="position:absolute;left:5.00px;top:619.50px" class="cls_007"><span class="cls_007">AffectsParentArrange</span><span class="cls_004"> and </span><span class="cls_007">AffectsParentMeasure</span><span class="cls_004"> members. These are typically used with</span></div>
<div style="position:absolute;left:5.00px;top:637.50px" class="cls_004"><span class="cls_004">Dependency Properties that have been declared in custom panels, or other UI controls,</span></div>
<div style="position:absolute;left:5.00px;top:655.50px" class="cls_004"><span class="cls_004">where the property value affects the look of the control and changes to it need to cause a</span></div>
<div style="position:absolute;left:5.00px;top:673.50px" class="cls_004"><span class="cls_004">visual update.</span></div>
<div style="position:absolute;left:5.00px;top:691.50px" class="cls_004"><span class="cls_004">It should also be noted that this </span><span class="cls_007">FrameworkPropertyMetadataOptions</span><span class="cls_004"> enumeration is</span></div>
<div style="position:absolute;left:5.00px;top:709.50px" class="cls_004"><span class="cls_004">declared with the </span><span class="cls_007">FlagsAttribute</span><span class="cls_004"> attribute, which signifies that we can also allocate a</span></div>
<div style="position:absolute;left:5.00px;top:727.50px" class="cls_004"><span class="cls_004">bitwise combination of its instance values, and therefore set multiple options for each of our</span></div>
<div style="position:absolute;left:5.00px;top:745.50px" class="cls_004"><span class="cls_004">Dependency Properties.</span></div>
<div style="position:absolute;left:52.98px;top:768.75px" class="cls_007"><span class="cls_007">public static readonly DependencyProperty HoursProperty =</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:116290px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background147.jpg" width=612 height=792></div>
<div style="position:absolute;left:67.97px;top:3.00px" class="cls_007"><span class="cls_007">DependencyProperty.Register(nameof(Hours), typeof(int),</span></div>
<div style="position:absolute;left:67.97px;top:16.50px" class="cls_007"><span class="cls_007">typeof(DurationPicker), new FrameworkPropertyMetadata(0,</span></div>
<div style="position:absolute;left:67.97px;top:30.00px" class="cls_007"><span class="cls_007">FrameworkPropertyMetadataOptions.BindsTwoWayByDefault |</span></div>
<div style="position:absolute;left:67.97px;top:43.50px" class="cls_007"><span class="cls_007">FrameworkPropertyMetadataOptions.AffectsMeasure, OnHoursChanged,</span></div>
<div style="position:absolute;left:67.97px;top:57.00px" class="cls_007"><span class="cls_007">CoerceHoursValue));</span></div>
<div style="position:absolute;left:5.00px;top:77.25px" class="cls_004"><span class="cls_004">In order to set the default value for the </span><span class="cls_007">Binding.UpdateSourceTrigger</span><span class="cls_004"> property, we need to</span></div>
<div style="position:absolute;left:5.00px;top:95.25px" class="cls_004"><span class="cls_004">use the most heavily populated constructor, passing all six input parameters. It is however,</span></div>
<div style="position:absolute;left:5.00px;top:113.25px" class="cls_004"><span class="cls_004">perfectly fine to pass null values for the callback handlers, if we don't need to use them.</span></div>
<div style="position:absolute;left:52.98px;top:136.50px" class="cls_007"><span class="cls_007">public static readonly DependencyProperty HoursProperty =</span></div>
<div style="position:absolute;left:67.97px;top:150.00px" class="cls_007"><span class="cls_007">DependencyProperty.Register(nameof(Hours), typeof(int),</span></div>
<div style="position:absolute;left:67.97px;top:163.50px" class="cls_007"><span class="cls_007">typeof(DurationPicker), new FrameworkPropertyMetadata(0,</span></div>
<div style="position:absolute;left:67.97px;top:177.00px" class="cls_007"><span class="cls_007">FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,</span></div>
<div style="position:absolute;left:52.98px;top:190.50px" class="cls_007"><span class="cls_007">OnHoursChanged,</span></div>
<div style="position:absolute;left:67.97px;top:204.00px" class="cls_007"><span class="cls_007">CoerceHoursValue, false, UpdateSourceTrigger.PropertyChanged));</span></div>
<div style="position:absolute;left:5.00px;top:224.25px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">false</span><span class="cls_004"> before the </span><span class="cls_007">UpdateSourceTrigger</span><span class="cls_004"> value sets the </span><span class="cls_007">IsAnimationProhibited</span></div>
<div style="position:absolute;left:5.00px;top:242.25px" class="cls_004"><span class="cls_004">property of the </span><span class="cls_007">UIPropertyMetadata</span><span class="cls_004"> class. The </span><span class="cls_007">UpdateSourceTrigger</span><span class="cls_004"> value set here will be</span></div>
<div style="position:absolute;left:5.00px;top:260.25px" class="cls_004"><span class="cls_004">used on all bindings to this property that have not explicitly set the </span><span class="cls_007">UpdateSourceTrigger</span></div>
<div style="position:absolute;left:5.00px;top:278.25px" class="cls_004"><span class="cls_004">property on the binding, or have set the </span><span class="cls_007">UpdateSourceTrigger.Default</span><span class="cls_004"> member to the</span></div>
<div style="position:absolute;left:5.00px;top:296.25px" class="cls_004"><span class="cls_004">binding property.</span></div>
<div style="position:absolute;left:5.00px;top:314.25px" class="cls_004"><span class="cls_004">Now that we have fully investigated the various options that we have when we declare</span></div>
<div style="position:absolute;left:5.00px;top:332.25px" class="cls_004"><span class="cls_004">Dependency Properties using the </span><span class="cls_007">Register</span><span class="cls_004"> method of the </span><span class="cls_007">DependencyProperty</span><span class="cls_004"> class, let's</span></div>
<div style="position:absolute;left:5.00px;top:350.25px" class="cls_004"><span class="cls_004">take a look at the another registration method from this class.</span></div>
<div style="position:absolute;left:5.00px;top:367.51px" class="cls_011"><span class="cls_011">Declaring read-only Dependency Properties</span></div>
<div style="position:absolute;left:5.00px;top:397.50px" class="cls_004"><span class="cls_004">Typically, read-only Dependency Properties are most commonly found in custom controls in</span></div>
<div style="position:absolute;left:5.00px;top:415.50px" class="cls_004"><span class="cls_004">situations where we need to data bind to a value, but do not want it to be publicly</span></div>
<div style="position:absolute;left:5.00px;top:433.50px" class="cls_004"><span class="cls_004">accessible. It might be a property that holds some relation to an on screen visual, mid</span></div>
<div style="position:absolute;left:5.00px;top:451.50px" class="cls_004"><span class="cls_004">calculation point, or previous value, but generally, we don't want the users of our framework</span></div>
<div style="position:absolute;left:5.00px;top:469.50px" class="cls_004"><span class="cls_004">to be able to data bind to it.</span></div>
<div style="position:absolute;left:5.00px;top:487.50px" class="cls_004"><span class="cls_004">Let's imagine a scenario where we want to create a button that will enable us to set a</span></div>
<div style="position:absolute;left:5.00px;top:505.50px" class="cls_004"><span class="cls_004">tooltip message to display when the control is disabled, in addition to the normal tooltip</span></div>
<div style="position:absolute;left:5.00px;top:523.50px" class="cls_004"><span class="cls_004">message. In this case, we could declare one Dependency Property to hold the disabled</span></div>
<div style="position:absolute;left:5.00px;top:541.50px" class="cls_004"><span class="cls_004">tooltip message and another to store the value of the original tooltip when displaying the</span></div>
<div style="position:absolute;left:5.00px;top:559.50px" class="cls_004"><span class="cls_004">disabled tooltip. This original tooltip property is a perfect candidate to be a read-only</span></div>
<div style="position:absolute;left:5.00px;top:577.50px" class="cls_004"><span class="cls_004">Dependency Property. Let's see what this property looks like.</span></div>
<div style="position:absolute;left:52.98px;top:600.75px" class="cls_007"><span class="cls_007">private static readonly DependencyPropertyKey</span></div>
<div style="position:absolute;left:52.98px;top:614.25px" class="cls_007"><span class="cls_007">originalToolTipPropertyKey =</span></div>
<div style="position:absolute;left:67.97px;top:627.75px" class="cls_007"><span class="cls_007">DependencyProperty.RegisterReadOnly("OriginalToolTip",</span></div>
<div style="position:absolute;left:52.98px;top:641.25px" class="cls_007"><span class="cls_007">typeof(string),</span></div>
<div style="position:absolute;left:67.97px;top:654.75px" class="cls_007"><span class="cls_007">typeof(TooltipTextBox), new PropertyMetadata());</span></div>
<div style="position:absolute;left:52.98px;top:681.75px" class="cls_007"><span class="cls_007">public static readonly DependencyProperty OriginalToolTipProperty =</span></div>
<div style="position:absolute;left:67.97px;top:695.25px" class="cls_007"><span class="cls_007">originalToolTipPropertyKey.DependencyProperty;</span></div>
<div style="position:absolute;left:52.98px;top:722.25px" class="cls_007"><span class="cls_007">public static string GetOriginalToolTip(DependencyObject</span></div>
<div style="position:absolute;left:52.98px;top:735.75px" class="cls_007"><span class="cls_007">dependencyObject)</span></div>
<div style="position:absolute;left:52.98px;top:749.25px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:762.75px" class="cls_007"><span class="cls_007">return</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:117092px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background148.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:3.00px" class="cls_007"><span class="cls_007">(string)dependencyObject.GetValue(OriginalToolTipProperty);</span></div>
<div style="position:absolute;left:52.98px;top:16.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:49.50px" class="cls_004"><span class="cls_004">As you can see, we use a different syntax to declare read-only Dependency Properties.</span></div>
<div style="position:absolute;left:5.00px;top:67.50px" class="cls_004"><span class="cls_004">Instead of returning the </span><span class="cls_007">DependencyProperty</span><span class="cls_004"> identifier that is returned from the </span><span class="cls_007">Register</span></div>
<div style="position:absolute;left:5.00px;top:85.50px" class="cls_004"><span class="cls_004">method, the </span><span class="cls_007">RegisterReadOnly</span><span class="cls_004"> method returns a </span><span class="cls_007">DependencyPropertyKey</span><span class="cls_004"> object.</span></div>
<div style="position:absolute;left:5.00px;top:103.50px" class="cls_004"><span class="cls_004">This object is typically declared with a </span><span class="cls_007">private</span><span class="cls_004"> access modifier, to stop it from being</span></div>
<div style="position:absolute;left:5.00px;top:121.50px" class="cls_004"><span class="cls_004">externally used with the </span><span class="cls_007">DependencyObject.SetValue</span><span class="cls_004"> method. However, this method can be</span></div>
<div style="position:absolute;left:5.00px;top:139.50px" class="cls_004"><span class="cls_004">used within the class that registered the read-only property to set its value.</span></div>
<div style="position:absolute;left:5.00px;top:157.50px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">DependencyProperty</span><span class="cls_004"> property of the </span><span class="cls_007">DependencyPropertyKey</span><span class="cls_004"> object is used to return</span></div>
<div style="position:absolute;left:5.00px;top:175.50px" class="cls_004"><span class="cls_004">the actual </span><span class="cls_007">DependencyProperty</span><span class="cls_004"> identifier that is used to access the property value from the</span></div>
<div style="position:absolute;left:5.00px;top:193.50px" class="cls_004"><span class="cls_004">dictionary that we discussed earlier.</span></div>
<div style="position:absolute;left:5.00px;top:211.50px" class="cls_004"><span class="cls_004">The input parameters of the </span><span class="cls_007">RegisterReadOnly</span><span class="cls_004"> methods offer the same options as those of</span></div>
<div style="position:absolute;left:5.00px;top:229.50px" class="cls_004"><span class="cls_004">the standard </span><span class="cls_007">Register</span><span class="cls_004"> method, although there is one less overload. Unlike the </span><span class="cls_007">Register</span></div>
<div style="position:absolute;left:5.00px;top:247.50px" class="cls_004"><span class="cls_004">method, when calling the </span><span class="cls_007">RegisterReadOnly</span><span class="cls_004"> methods, we always need to provide the</span></div>
<div style="position:absolute;left:5.00px;top:265.50px" class="cls_007"><span class="cls_007">PropertyMetadata</span><span class="cls_004"> object, although we can pass a null value if we do not need what it</span></div>
<div style="position:absolute;left:5.00px;top:283.50px" class="cls_004"><span class="cls_004">provides.</span></div>
<div style="position:absolute;left:5.00px;top:301.50px" class="cls_004"><span class="cls_004">One very important point to note is that when data binding to a read-only Dependency</span></div>
<div style="position:absolute;left:5.00px;top:319.50px" class="cls_004"><span class="cls_004">Property, we </span><span class="cls_006">must</span><span class="cls_004"> set the binding </span><span class="cls_007">Mode</span><span class="cls_004"> property to the </span><span class="cls_007">OneWay</span><span class="cls_004"> enumeration member. Failure</span></div>
<div style="position:absolute;left:5.00px;top:338.25px" class="cls_004"><span class="cls_004">to do so will result in an error at runtime. We've now covered the creation of normal</span></div>
<div style="position:absolute;left:5.00px;top:356.25px" class="cls_004"><span class="cls_004">Dependency Properties in some detail, so let's move on to take a look at a different kind</span></div>
<div style="position:absolute;left:5.00px;top:374.25px" class="cls_004"><span class="cls_004">Dependency Property.</span></div>
<div style="position:absolute;left:5.00px;top:391.51px" class="cls_011"><span class="cls_011">Registering Attached Properties</span></div>
<div style="position:absolute;left:5.00px;top:421.50px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">DependencyProperty</span><span class="cls_004"> class enables us to register one further, special type of</span></div>
<div style="position:absolute;left:5.00px;top:439.50px" class="cls_004"><span class="cls_004">Dependency Property. These properties are like the Extension methods of XAML, as they</span></div>
<div style="position:absolute;left:5.00px;top:457.50px" class="cls_004"><span class="cls_004">enable us to extend existing classes with our own functionality. They are of course,</span></div>
<div style="position:absolute;left:5.00px;top:475.50px" class="cls_004"><span class="cls_004">Attached Properties.</span></div>
<div style="position:absolute;left:5.00px;top:493.50px" class="cls_004"><span class="cls_004">We've already seen some examples of them earlier in this book and we'll see further</span></div>
<div style="position:absolute;left:5.00px;top:511.50px" class="cls_004"><span class="cls_004">examples later, but in this chapter, we'll cover their registration. We can declare Attached</span></div>
<div style="position:absolute;left:5.00px;top:529.50px" class="cls_004"><span class="cls_004">Properties in exactly the same ways that we can create Dependency Properties and have</span></div>
<div style="position:absolute;left:5.00px;top:547.50px" class="cls_004"><span class="cls_004">all of the same various options of setting metadata and attaching handlers.</span></div>
<div style="position:absolute;left:5.00px;top:565.50px" class="cls_004"><span class="cls_004">There are several overloads of the </span><span class="cls_007">RegisterAttached</span><span class="cls_004"> and </span><span class="cls_007">RegisterAttachedReadOnly</span></div>
<div style="position:absolute;left:5.00px;top:583.50px" class="cls_004"><span class="cls_004">methods that mirror the </span><span class="cls_007">Register</span><span class="cls_004"> and </span><span class="cls_007">RegisterReadOnly</span><span class="cls_004"> methods in input parameters and</span></div>
<div style="position:absolute;left:5.00px;top:601.50px" class="cls_004"><span class="cls_004">functionality. However, instead of declaring a CLR wrapper for our Attached Properties, we</span></div>
<div style="position:absolute;left:5.00px;top:619.50px" class="cls_004"><span class="cls_004">are required to declare a pair of getter and setter methods to access and set their values.</span></div>
<div style="position:absolute;left:5.00px;top:637.50px" class="cls_004"><span class="cls_004">Let's see another example from the </span><span class="cls_007">TextBoxProperties</span><span class="cls_004"> class.</span></div>
<div style="position:absolute;left:52.98px;top:660.75px" class="cls_007"><span class="cls_007">public static DependencyProperty IsFocusedProperty =</span></div>
<div style="position:absolute;left:67.97px;top:674.25px" class="cls_007"><span class="cls_007">DependencyProperty.RegisterAttached("IsFocused",</span></div>
<div style="position:absolute;left:67.97px;top:687.75px" class="cls_007"><span class="cls_007">typeof(bool), typeof(TextBoxProperties),</span></div>
<div style="position:absolute;left:67.97px;top:701.25px" class="cls_007"><span class="cls_007">new PropertyMetadata(false, OnIsFocusedChanged));</span></div>
<div style="position:absolute;left:52.98px;top:728.25px" class="cls_007"><span class="cls_007">public static bool GetIsFocused(DependencyObject dependencyObject)</span></div>
<div style="position:absolute;left:52.98px;top:741.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:755.25px" class="cls_007"><span class="cls_007">return (bool)dependencyObject.GetValue(IsFocusedProperty);</span></div>
<div style="position:absolute;left:52.98px;top:768.75px" class="cls_007"><span class="cls_007">}</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:117894px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background149.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:16.50px" class="cls_007"><span class="cls_007">public static void SetIsFocused(DependencyObject dependencyObject,</span></div>
<div style="position:absolute;left:67.97px;top:30.00px" class="cls_007"><span class="cls_007">bool value)</span></div>
<div style="position:absolute;left:52.98px;top:43.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:57.00px" class="cls_007"><span class="cls_007">dependencyObject.SetValue(IsFocusedProperty, value);</span></div>
<div style="position:absolute;left:52.98px;top:70.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:97.50px" class="cls_007"><span class="cls_007">public static void OnIsFocusedChanged(DependencyObject</span></div>
<div style="position:absolute;left:52.98px;top:111.00px" class="cls_007"><span class="cls_007">dependencyObject,</span></div>
<div style="position:absolute;left:67.97px;top:124.50px" class="cls_007"><span class="cls_007">DependencyPropertyChangedEventArgs e)</span></div>
<div style="position:absolute;left:52.98px;top:138.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:151.50px" class="cls_007"><span class="cls_007">TextBox textBox = dependencyObject as TextBox;</span></div>
<div style="position:absolute;left:67.97px;top:165.00px" class="cls_007"><span class="cls_007">if ((bool)e.NewValue && !(bool)e.OldValue && !textBox.IsFocused)</span></div>
<div style="position:absolute;left:82.97px;top:178.50px" class="cls_007"><span class="cls_007">textBox.Focus();</span></div>
<div style="position:absolute;left:52.98px;top:192.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:225.00px" class="cls_004"><span class="cls_004">Here, we have the declaration of a </span><span class="cls_007">bool</span><span class="cls_004"> Attached Property named </span><span class="cls_007">IsFocused</span><span class="cls_004"> with a</span></div>
<div style="position:absolute;left:5.00px;top:243.00px" class="cls_007"><span class="cls_007">PropertyMetadata</span><span class="cls_004"> element that specifies a default value and a </span><span class="cls_007">PropertyChangedCallback</span></div>
<div style="position:absolute;left:5.00px;top:261.00px" class="cls_004"><span class="cls_004">handler. Like the CLR property wrappers for Dependency Properties, these getter and</span></div>
<div style="position:absolute;left:5.00px;top:279.00px" class="cls_004"><span class="cls_004">setter methods will not be called by the WPF Framework. They are typically declared both</span></div>
<div style="position:absolute;left:5.00px;top:297.00px" class="cls_004"><span class="cls_004">public and static.</span></div>
<div style="position:absolute;left:5.00px;top:315.00px" class="cls_004"><span class="cls_004">However, there is one situation where we do not need to declare these methods public. If</span></div>
<div style="position:absolute;left:5.00px;top:333.00px" class="cls_004"><span class="cls_004">we want to create a Dependency Property whose value can be inherited by its children,</span></div>
<div style="position:absolute;left:5.00px;top:351.00px" class="cls_004"><span class="cls_004">then we should declare it using the </span><span class="cls_007">RegisterAttached</span><span class="cls_004"> method, even if we don't require an</span></div>
<div style="position:absolute;left:5.00px;top:369.00px" class="cls_004"><span class="cls_004">Attached Property. In this situation, we are not required to publicly expose our property</span></div>
<div style="position:absolute;left:5.00px;top:387.00px" class="cls_004"><span class="cls_004">getter and setter.</span></div>
<div style="position:absolute;left:5.00px;top:405.00px" class="cls_004"><span class="cls_004">Although we can specify the </span><span class="cls_007">FrameworkPropertyMetadataOptions.Inherits</span><span class="cls_004"> metadata</span></div>
<div style="position:absolute;left:5.00px;top:423.00px" class="cls_004"><span class="cls_004">option upon the declaration of Dependency Properties and their value inheritance might</span></div>
<div style="position:absolute;left:5.00px;top:441.00px" class="cls_004"><span class="cls_004">work in some situations, it is not guaranteed in other situations. As Attached Properties are</span></div>
<div style="position:absolute;left:5.00px;top:459.00px" class="cls_004"><span class="cls_004">global properties in the property system, we can be assured that their property value</span></div>
<div style="position:absolute;left:5.00px;top:477.00px" class="cls_004"><span class="cls_004">inheritance will work in all situations.</span></div>
<div style="position:absolute;left:5.00px;top:495.00px" class="cls_004"><span class="cls_004">Returning to our example, our </span><span class="cls_007">PropertyChangedCallback</span><span class="cls_004"> handler is a simple affair. It casts</span></div>
<div style="position:absolute;left:5.00px;top:513.00px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">dependencyObject</span><span class="cls_004"> property to the type of control that the property is attached to, in this</span></div>
<div style="position:absolute;left:5.00px;top:531.00px" class="cls_004"><span class="cls_004">case, a </span><span class="cls_007">TextBox</span><span class="cls_004">. It then verifies that the data bound </span><span class="cls_007">bool</span><span class="cls_004"> value has been set from </span><span class="cls_007">false</span><span class="cls_004"> to</span></div>
<div style="position:absolute;left:5.00px;top:549.00px" class="cls_007"><span class="cls_007">true</span><span class="cls_004"> and that the control is not already focused. If these conditions are verified, the control</span></div>
<div style="position:absolute;left:5.00px;top:567.00px" class="cls_004"><span class="cls_004">is then focused.</span></div>
<div style="position:absolute;left:5.00px;top:585.00px" class="cls_004"><span class="cls_004">This Attached Property can be data bound to a </span><span class="cls_007">bool</span><span class="cls_004"> property in a View Model like this.</span></div>
<div style="position:absolute;left:52.98px;top:608.25px" class="cls_007"><span class="cls_007">xmlns:Attached="clr-</span></div>
<div style="position:absolute;left:52.98px;top:621.75px" class="cls_007"><span class="cls_007">namespace:CompanyName.ApplicationName.Views.Attached"</span></div>
<div style="position:absolute;left:52.98px;top:648.75px" class="cls_007"><span class="cls_007"><TextBox Attached:TextBoxProperties.IsFocused="{Binding IsFocused}"</span></div>
<div style="position:absolute;left:67.97px;top:662.25px" class="cls_007"><span class="cls_007">Text="{Binding User.Name}" /></span></div>
<div style="position:absolute;left:5.00px;top:695.25px" class="cls_004"><span class="cls_004">The attached textbox control can then be focused from the View Model at any time using</span></div>
<div style="position:absolute;left:5.00px;top:713.25px" class="cls_004"><span class="cls_004">this following method:</span></div>
<div style="position:absolute;left:52.98px;top:736.50px" class="cls_007"><span class="cls_007">private void Focus()</span></div>
<div style="position:absolute;left:52.98px;top:750.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:763.50px" class="cls_007"><span class="cls_007">IsFocused = false;</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:118696px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background150.jpg" width=612 height=792></div>
<div style="position:absolute;left:67.97px;top:3.00px" class="cls_007"><span class="cls_007">IsFocused = true;</span></div>
<div style="position:absolute;left:52.98px;top:16.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:36.75px" class="cls_004"><span class="cls_004">Note that we need to ensure that the variable is </span><span class="cls_007">false</span><span class="cls_004"> before setting it to </span><span class="cls_007">true</span><span class="cls_004">, as it is the</span></div>
<div style="position:absolute;left:5.00px;top:54.75px" class="cls_004"><span class="cls_004">actual changing of the value that will trigger the control to become focused. Now that we</span></div>
<div style="position:absolute;left:5.00px;top:72.75px" class="cls_004"><span class="cls_004">know how to declare our own custom Dependency Properties, let's turn our attention to the</span></div>
<div style="position:absolute;left:5.00px;top:90.75px" class="cls_004"><span class="cls_004">rules that govern the way they are set.</span></div>
<div style="position:absolute;left:5.00px;top:108.01px" class="cls_011"><span class="cls_011">Prioritizing value setting sources</span></div>
<div style="position:absolute;left:5.00px;top:138.00px" class="cls_004"><span class="cls_004">As we have already seen, there are a number of ways of setting the values of Dependency</span></div>
<div style="position:absolute;left:5.00px;top:156.00px" class="cls_004"><span class="cls_004">Properties; we can set them directly in code, locally in XAML, or through the use of our</span></div>
<div style="position:absolute;left:5.00px;top:174.00px" class="cls_007"><span class="cls_007">CoerceValueCallback</span><span class="cls_004"> handlers for example. However, there are many more ways that they</span></div>
<div style="position:absolute;left:5.00px;top:192.00px" class="cls_004"><span class="cls_004">can be set. For example, they can also be set in styles, animations, or through property</span></div>
<div style="position:absolute;left:5.00px;top:210.00px" class="cls_004"><span class="cls_004">inheritance to name but a few.</span></div>
<div style="position:absolute;left:5.00px;top:228.00px" class="cls_004"><span class="cls_004">When we data bind our View Model properties to Dependency Properties and find that the</span></div>
<div style="position:absolute;left:5.00px;top:246.00px" class="cls_004"><span class="cls_004">displayed value is not what we are expecting, one reason for this can be because another</span></div>
<div style="position:absolute;left:5.00px;top:264.00px" class="cls_004"><span class="cls_004">method of setting the property has a higher precedence and so overrides our expected</span></div>
<div style="position:absolute;left:5.00px;top:282.00px" class="cls_004"><span class="cls_004">value. This is because all of the methods of setting the values of Dependency Properties</span></div>
<div style="position:absolute;left:5.00px;top:300.00px" class="cls_004"><span class="cls_004">are ordered in terms of importance in a list called the Dependency Property Setting</span></div>
<div style="position:absolute;left:5.00px;top:318.00px" class="cls_004"><span class="cls_004">Precedence List.</span></div>
<div style="position:absolute;left:13.25px;top:336.00px" class="cls_004"><span class="cls_004">1. Property system coercion.</span></div>
<div style="position:absolute;left:13.25px;top:354.00px" class="cls_004"><span class="cls_004">2. Animated properties.</span></div>
<div style="position:absolute;left:13.25px;top:372.00px" class="cls_004"><span class="cls_004">3. Local value.</span></div>
<div style="position:absolute;left:13.25px;top:390.00px" class="cls_004"><span class="cls_004">4. Template properties.</span></div>
<div style="position:absolute;left:13.25px;top:408.00px" class="cls_004"><span class="cls_004">5. Implicit style (only applies to the </span><span class="cls_007">Style</span><span class="cls_004"> property).</span></div>
<div style="position:absolute;left:13.25px;top:426.00px" class="cls_004"><span class="cls_004">6. Style triggers.</span></div>
<div style="position:absolute;left:13.25px;top:444.00px" class="cls_004"><span class="cls_004">7. Template triggers.</span></div>
<div style="position:absolute;left:13.25px;top:462.00px" class="cls_004"><span class="cls_004">8. Style setters.</span></div>
<div style="position:absolute;left:13.25px;top:480.00px" class="cls_004"><span class="cls_004">9. Default (theme) style.</span></div>
<div style="position:absolute;left:5.00px;top:498.00px" class="cls_004"><span class="cls_004">10. Inheritance.</span></div>
<div style="position:absolute;left:6.50px;top:516.00px" class="cls_004"><span class="cls_004">11. Default value from Dependency Property metadata.</span></div>
<div style="position:absolute;left:5.00px;top:534.00px" class="cls_004"><span class="cls_004">Last on the list, with the lowest precedence at position eleven, are the default values that</span></div>
<div style="position:absolute;left:5.00px;top:552.00px" class="cls_004"><span class="cls_004">are specified in the Dependency Property declarations. Next up the list are changes caused</span></div>
<div style="position:absolute;left:5.00px;top:570.00px" class="cls_004"><span class="cls_004">by property inheritance. Remember that this can be defined in our Dependency Properties</span></div>
<div style="position:absolute;left:5.00px;top:588.00px" class="cls_004"><span class="cls_004">using the </span><span class="cls_007">Inherits</span><span class="cls_004"> instance of the</span><span class="cls_007"> FrameworkPropertyMetadataOptions</span><span class="cls_004"> enumeration in the</span></div>
<div style="position:absolute;left:5.00px;top:606.00px" class="cls_007"><span class="cls_007">FrameworkPropertyMetadata</span><span class="cls_004"> input parameter of the </span><span class="cls_007">DependencyProperty.Register</span><span class="cls_004"> method.</span></div>
<div style="position:absolute;left:5.00px;top:624.00px" class="cls_004"><span class="cls_004">Let's see an example of this to highlight this order of precedence.</span></div>
<div style="position:absolute;left:52.98px;top:647.25px" class="cls_007"><span class="cls_007"><StackPanel TextElement.FontSize="20"></span></div>
<div style="position:absolute;left:67.97px;top:660.75px" class="cls_007"><span class="cls_007"><TextBlock Text="Black Text" /></span></div>
<div style="position:absolute;left:67.97px;top:674.25px" class="cls_007"><span class="cls_007"><StackPanel Orientation="Horizontal"</span></div>
<div style="position:absolute;left:52.98px;top:687.75px" class="cls_007"><span class="cls_007">TextElement.Foreground="Red"></span></div>
<div style="position:absolute;left:82.97px;top:701.25px" class="cls_007"><span class="cls_007"><TextBlock Text="Red Text" /></span></div>
<div style="position:absolute;left:67.97px;top:714.75px" class="cls_007"><span class="cls_007"></StackPanel></span></div>
<div style="position:absolute;left:52.98px;top:728.25px" class="cls_007"><span class="cls_007"></StackPanel></span></div>
<div style="position:absolute;left:5.00px;top:748.50px" class="cls_004"><span class="cls_004">In this first example, the </span><span class="cls_007">TextBlock</span><span class="cls_004"> control in the outer </span><span class="cls_007">StackPanel</span><span class="cls_004"> has its </span><span class="cls_007">Foreground</span><span class="cls_004"> color</span></div>
<div style="position:absolute;left:5.00px;top:766.50px" class="cls_004"><span class="cls_004">set to black by the default value that was set in the data bound </span><span class="cls_007">Text</span><span class="cls_004"> property. However, the</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:119498px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background151.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_007"><span class="cls_007">TextBlock</span><span class="cls_004"> control inside the inner </span><span class="cls_007">StackPanel</span><span class="cls_004"> has its default </span><span class="cls_007">Foreground</span><span class="cls_004"> property value</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">overridden by the </span><span class="cls_007">TextElement.Foreground</span><span class="cls_004"> Attached Property value that is set on its parent</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">control. It inherits the value of this property from the </span><span class="cls_007">StackPanel</span><span class="cls_004"> and this demonstrates that</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">properties set through property inheritance have a higher precedence than properties set</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">with default values.</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">However, default property values that are set in theme styles follow on the precedence list,</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">with the next lowest priority, and override property values set through inheritance. As it is</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">quite difficult to come up with a short XAML example for this, we'll skip over this item and</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">move onto the next. At number eight on the list, we have property values that have been set</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">by style setters. Let's adjust our earlier example to demonstrate this.</span></div>
<div style="position:absolute;left:52.98px;top:189.00px" class="cls_007"><span class="cls_007"><StackPanel TextElement.FontSize="20"></span></div>
<div style="position:absolute;left:67.97px;top:202.50px" class="cls_007"><span class="cls_007"><TextBlock Text="Black Text" /></span></div>
<div style="position:absolute;left:67.97px;top:216.00px" class="cls_007"><span class="cls_007"><StackPanel Orientation="Horizontal"</span></div>
<div style="position:absolute;left:52.98px;top:229.50px" class="cls_007"><span class="cls_007">TextElement.Foreground="Red"></span></div>
<div style="position:absolute;left:82.97px;top:243.00px" class="cls_007"><span class="cls_007"><TextBlock Text="Red Text" Margin="0,0,10,0" /></span></div>
<div style="position:absolute;left:82.97px;top:256.50px" class="cls_007"><span class="cls_007"><TextBlock Text="Green Text"></span></div>
<div style="position:absolute;left:97.96px;top:270.00px" class="cls_007"><span class="cls_007"><TextBlock.Style></span></div>
<div style="position:absolute;left:112.96px;top:283.50px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type TextBlock}"></span></div>
<div style="position:absolute;left:127.95px;top:297.00px" class="cls_007"><span class="cls_007"><Setter Property="Foreground" Value="Green" /></span></div>
<div style="position:absolute;left:112.96px;top:310.50px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:97.96px;top:324.00px" class="cls_007"><span class="cls_007"></TextBlock.Style></span></div>
<div style="position:absolute;left:82.97px;top:337.50px" class="cls_007"><span class="cls_007"></TextBlock></span></div>
<div style="position:absolute;left:67.97px;top:351.00px" class="cls_007"><span class="cls_007"></StackPanel></span></div>
<div style="position:absolute;left:52.98px;top:364.50px" class="cls_007"><span class="cls_007"></StackPanel></span></div>
<div style="position:absolute;left:5.00px;top:384.75px" class="cls_004"><span class="cls_004">In this example, the </span><span class="cls_007">TextBlock</span><span class="cls_004"> control in the outer </span><span class="cls_007">StackPanel</span><span class="cls_004"> still has its </span><span class="cls_007">Foreground</span><span class="cls_004"> color</span></div>
<div style="position:absolute;left:5.00px;top:402.75px" class="cls_004"><span class="cls_004">set to black by the default value of the data bound </span><span class="cls_007">Text</span><span class="cls_004"> property. The top </span><span class="cls_007">TextBlock</span><span class="cls_004"> control</span></div>
<div style="position:absolute;left:5.00px;top:420.75px" class="cls_004"><span class="cls_004">inside the inner </span><span class="cls_007">StackPanel</span><span class="cls_004"> still has its default </span><span class="cls_007">Foreground</span><span class="cls_004"> property value overridden by the</span></div>
<div style="position:absolute;left:5.00px;top:438.75px" class="cls_007"><span class="cls_007">TextElement.Foreground</span><span class="cls_004"> value from its parent control. However, now we can also see that</span></div>
<div style="position:absolute;left:5.00px;top:456.75px" class="cls_004"><span class="cls_004">values that are set in a </span><span class="cls_007">Style</span><span class="cls_004"> will override inherited property values. This is the output of</span></div>
<div style="position:absolute;left:5.00px;top:474.75px" class="cls_004"><span class="cls_004">this code snippet:</span></div>
<div style="position:absolute;left:5.00px;top:570.00px" class="cls_004"><span class="cls_004">Next, at number seven on the precedence list, we have template triggers, which override</span></div>
<div style="position:absolute;left:5.00px;top:588.00px" class="cls_004"><span class="cls_004">property values that are set with style setters and all other previously mentioned methods</span></div>
<div style="position:absolute;left:5.00px;top:606.00px" class="cls_004"><span class="cls_004">of setting values. Note that this specifically deals with triggers that are declared within</span></div>
<div style="position:absolute;left:5.00px;top:624.00px" class="cls_004"><span class="cls_004">templates, such as the </span><span class="cls_007">ControlTemplate</span><span class="cls_004">, and does not relate to triggers that are declared</span></div>
<div style="position:absolute;left:5.00px;top:642.00px" class="cls_004"><span class="cls_004">within any </span><span class="cls_007">Style.Triggers</span><span class="cls_004"> collections. Let's look at an example.</span></div>
<div style="position:absolute;left:52.98px;top:665.25px" class="cls_007"><span class="cls_007"><Button Content="Blue Text" FontSize="20"></span></div>
<div style="position:absolute;left:67.97px;top:678.75px" class="cls_007"><span class="cls_007"><Button.Style></span></div>
<div style="position:absolute;left:82.97px;top:692.25px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type Button}"></span></div>
<div style="position:absolute;left:97.96px;top:705.75px" class="cls_007"><span class="cls_007"><Setter Property="Foreground" Value="Green" /></span></div>
<div style="position:absolute;left:97.96px;top:719.25px" class="cls_007"><span class="cls_007"><Setter Property="Control.Template"></span></div>
<div style="position:absolute;left:112.96px;top:732.75px" class="cls_007"><span class="cls_007"><Setter.Value></span></div>
<div style="position:absolute;left:127.95px;top:746.25px" class="cls_007"><span class="cls_007"><ControlTemplate TargetType="{x:Type Button}"></span></div>
<div style="position:absolute;left:142.94px;top:759.75px" class="cls_007"><span class="cls_007"><ContentPresenter /></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:120300px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background152.jpg" width=612 height=792></div>
<div style="position:absolute;left:142.94px;top:3.00px" class="cls_007"><span class="cls_007"><ControlTemplate.Triggers></span></div>
<div style="position:absolute;left:157.94px;top:16.50px" class="cls_007"><span class="cls_007"><Trigger Property="IsEnabled" Value="True"></span></div>
<div style="position:absolute;left:172.93px;top:30.00px" class="cls_007"><span class="cls_007"><Setter Property="Foreground" Value="Blue" /></span></div>
<div style="position:absolute;left:157.94px;top:43.50px" class="cls_007"><span class="cls_007"></Trigger></span></div>
<div style="position:absolute;left:142.94px;top:57.00px" class="cls_007"><span class="cls_007"></ControlTemplate.Triggers></span></div>
<div style="position:absolute;left:127.95px;top:70.50px" class="cls_007"><span class="cls_007"></ControlTemplate></span></div>
<div style="position:absolute;left:112.96px;top:84.00px" class="cls_007"><span class="cls_007"></Setter.Value></span></div>
<div style="position:absolute;left:97.96px;top:97.50px" class="cls_007"><span class="cls_007"></Setter></span></div>
<div style="position:absolute;left:82.97px;top:111.00px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:67.97px;top:124.50px" class="cls_007"><span class="cls_007"></Button.Style></span></div>
<div style="position:absolute;left:52.98px;top:138.00px" class="cls_007"><span class="cls_007"></Button></span></div>
<div style="position:absolute;left:5.00px;top:158.25px" class="cls_004"><span class="cls_004">In this example, we have declared a button and overridden its </span><span class="cls_007">ControlTemplate</span><span class="cls_004">, defining a</span></div>
<div style="position:absolute;left:5.00px;top:176.25px" class="cls_004"><span class="cls_004">new, minimal markup for it. In the style, we have set the </span><span class="cls_007">Foreground</span><span class="cls_004"> property value to</span></div>
<div style="position:absolute;left:5.00px;top:194.25px" class="cls_004"><span class="cls_004">green in a setter. However, in our </span><span class="cls_007">ControlTemplate</span><span class="cls_004">, we have a </span><span class="cls_007">Trigger</span><span class="cls_004"> that will override</span></div>
<div style="position:absolute;left:5.00px;top:212.25px" class="cls_004"><span class="cls_004">this value and set it to blue when its condition is met. Note that if we changed the trigger</span></div>
<div style="position:absolute;left:5.00px;top:230.25px" class="cls_004"><span class="cls_004">condition to </span><span class="cls_007">false</span><span class="cls_004">, or removed the whole trigger, the button text would then become green,</span></div>
<div style="position:absolute;left:5.00px;top:248.25px" class="cls_004"><span class="cls_004">as set by the style.</span></div>
<div style="position:absolute;left:5.00px;top:266.25px" class="cls_004"><span class="cls_004">Next up the list at position six are triggers that are declared within </span><span class="cls_007">Style.Triggers</span></div>
<div style="position:absolute;left:5.00px;top:284.25px" class="cls_004"><span class="cls_004">collections. One important point to note here is that this only relates to styles that are either</span></div>
<div style="position:absolute;left:5.00px;top:302.25px" class="cls_004"><span class="cls_004">declared inline locally, in the current control's </span><span class="cls_007">Resources</span><span class="cls_004"> section, or in the application</span></div>
<div style="position:absolute;left:5.00px;top:320.25px" class="cls_004"><span class="cls_004">resources file and not to default styles, which have a lower precedence value. We can</span></div>
<div style="position:absolute;left:5.00px;top:338.25px" class="cls_004"><span class="cls_004">extend our previous example by adding a new trigger into the </span><span class="cls_007">Style.Triggers</span><span class="cls_004"> collection to</span></div>
<div style="position:absolute;left:5.00px;top:356.25px" class="cls_004"><span class="cls_004">highlight this new priority.</span></div>
<div style="position:absolute;left:52.98px;top:379.50px" class="cls_007"><span class="cls_007"><Button Content="Orange Text" FontSize="20"></span></div>
<div style="position:absolute;left:67.97px;top:393.00px" class="cls_007"><span class="cls_007"><Button.Style></span></div>
<div style="position:absolute;left:82.97px;top:406.50px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type Button}"></span></div>
<div style="position:absolute;left:97.96px;top:420.00px" class="cls_007"><span class="cls_007"><Setter Property="Foreground" Value="Green" /></span></div>
<div style="position:absolute;left:97.96px;top:433.50px" class="cls_007"><span class="cls_007"><Setter Property="Control.Template"></span></div>
<div style="position:absolute;left:112.96px;top:447.00px" class="cls_007"><span class="cls_007"><Setter.Value></span></div>
<div style="position:absolute;left:127.95px;top:460.50px" class="cls_007"><span class="cls_007"><ControlTemplate TargetType="{x:Type Button}"></span></div>
<div style="position:absolute;left:142.94px;top:474.00px" class="cls_007"><span class="cls_007"><ContentPresenter /></span></div>
<div style="position:absolute;left:142.94px;top:487.50px" class="cls_007"><span class="cls_007"><ControlTemplate.Triggers></span></div>
<div style="position:absolute;left:157.94px;top:501.00px" class="cls_007"><span class="cls_007"><Trigger Property="IsEnabled" Value="True"></span></div>
<div style="position:absolute;left:172.93px;top:514.50px" class="cls_007"><span class="cls_007"><Setter Property="Foreground" Value="Blue" /></span></div>
<div style="position:absolute;left:157.94px;top:528.00px" class="cls_007"><span class="cls_007"></Trigger></span></div>
<div style="position:absolute;left:142.94px;top:541.50px" class="cls_007"><span class="cls_007"></ControlTemplate.Triggers></span></div>
<div style="position:absolute;left:127.95px;top:555.00px" class="cls_007"><span class="cls_007"></ControlTemplate></span></div>
<div style="position:absolute;left:112.96px;top:568.50px" class="cls_007"><span class="cls_007"></Setter.Value></span></div>
<div style="position:absolute;left:97.96px;top:582.00px" class="cls_007"><span class="cls_007"></Setter></span></div>
<div style="position:absolute;left:97.96px;top:595.50px" class="cls_007"><span class="cls_007"><Style.Triggers></span></div>
<div style="position:absolute;left:112.96px;top:609.00px" class="cls_007"><span class="cls_007"><Trigger Property="IsEnabled" Value="True"></span></div>
<div style="position:absolute;left:127.95px;top:622.50px" class="cls_007"><span class="cls_007"><Setter Property="Foreground" Value="Orange" /></span></div>
<div style="position:absolute;left:112.96px;top:636.00px" class="cls_007"><span class="cls_007"></Trigger></span></div>
<div style="position:absolute;left:97.96px;top:649.50px" class="cls_007"><span class="cls_007"></Style.Triggers></span></div>
<div style="position:absolute;left:82.97px;top:663.00px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:67.97px;top:676.50px" class="cls_007"><span class="cls_007"></Button.Style></span></div>
<div style="position:absolute;left:52.98px;top:690.00px" class="cls_007"><span class="cls_007"></Button></span></div>
<div style="position:absolute;left:5.00px;top:710.25px" class="cls_004"><span class="cls_004">When running this example, our text is now orange. The </span><span class="cls_007">Foreground</span><span class="cls_004"> property value that is</span></div>
<div style="position:absolute;left:5.00px;top:728.25px" class="cls_004"><span class="cls_004">set by the trigger in the </span><span class="cls_007">Triggers</span><span class="cls_004"> collection of the style has overridden the value set by the</span></div>
<div style="position:absolute;left:5.00px;top:746.25px" class="cls_004"><span class="cls_004">template trigger, which itself has overridden the value set by the style setter. Let's move on.</span></div>
<div style="position:absolute;left:5.00px;top:764.25px" class="cls_004"><span class="cls_004">At number five on the list, we have implicit styles. Note that this special level of precedence</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:121102px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background153.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">only applies to the </span><span class="cls_007">Style</span><span class="cls_004"> property and no others. A style can be implicitly set to all</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">members of a type, by specifying the target type and being declared without an </span><span class="cls_007">x:Key</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">directive set. Here is an example.</span></div>
<div style="position:absolute;left:52.98px;top:63.00px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type Button}"></span></div>
<div style="position:absolute;left:67.97px;top:76.50px" class="cls_007"><span class="cls_007"><Setter Property="Foreground" Value="Green" /></span></div>
<div style="position:absolute;left:52.98px;top:90.00px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:5.00px;top:110.25px" class="cls_004"><span class="cls_004">The relevant style must either be declared in the current XAML page, or the</span></div>
<div style="position:absolute;left:5.00px;top:128.25px" class="cls_007"><span class="cls_007">Application.Resources</span><span class="cls_004"> section of the </span><span class="cls_007">App.xaml</span><span class="cls_004"> file. Styles from themes are not included</span></div>
<div style="position:absolute;left:5.00px;top:146.25px" class="cls_004"><span class="cls_004">here, as they have a lower value precedence. Note that this special position in the list was</span></div>
<div style="position:absolute;left:5.00px;top:164.25px" class="cls_004"><span class="cls_004">only added in .NET 4 and is omitted from the .NET 3 documentation on the MSDN website.</span></div>
<div style="position:absolute;left:5.00px;top:182.25px" class="cls_004"><span class="cls_004">Next up the list at position four are properties that are set within either a </span><span class="cls_007">ControlTemplate</span></div>
<div style="position:absolute;left:5.00px;top:200.25px" class="cls_004"><span class="cls_004">or a </span><span class="cls_007">DataTemplate</span><span class="cls_004">. If we set a property directly on any element within a template, that</span></div>
<div style="position:absolute;left:5.00px;top:218.25px" class="cls_004"><span class="cls_004">value will override all values set by methods with lower precedence. For example, if we</span></div>
<div style="position:absolute;left:5.00px;top:236.25px" class="cls_004"><span class="cls_004">directly set the </span><span class="cls_007">Foreground</span><span class="cls_004"> property on the </span><span class="cls_007">ContentPresenter</span><span class="cls_004"> from our previous example,</span></div>
<div style="position:absolute;left:5.00px;top:254.25px" class="cls_004"><span class="cls_004">then it's value will override all other settings in that example and the button text will be red.</span></div>
<div style="position:absolute;left:52.98px;top:277.50px" class="cls_007"><span class="cls_007"><ControlTemplate TargetType="{x:Type Button}"></span></div>
<div style="position:absolute;left:67.97px;top:291.00px" class="cls_007"><span class="cls_007"><ContentPresenter TextElement.Foreground="Red" /></span></div>
<div style="position:absolute;left:67.97px;top:304.50px" class="cls_007"><span class="cls_007"><ControlTemplate.Triggers></span></div>
<div style="position:absolute;left:82.97px;top:318.00px" class="cls_007"><span class="cls_007"><Trigger Property="IsEnabled" Value="True"></span></div>
<div style="position:absolute;left:97.96px;top:331.50px" class="cls_007"><span class="cls_007"><Setter Property="Foreground" Value="Blue" /></span></div>
<div style="position:absolute;left:82.97px;top:345.00px" class="cls_007"><span class="cls_007"></Trigger></span></div>
<div style="position:absolute;left:67.97px;top:358.50px" class="cls_007"><span class="cls_007"></ControlTemplate.Triggers></span></div>
<div style="position:absolute;left:52.98px;top:372.00px" class="cls_007"><span class="cls_007"></ControlTemplate></span></div>
<div style="position:absolute;left:5.00px;top:392.25px" class="cls_004"><span class="cls_004">At position three on the list, we have locally set values. To demonstrate this, we could just</span></div>
<div style="position:absolute;left:5.00px;top:410.25px" class="cls_004"><span class="cls_004">set the </span><span class="cls_007">Foreground</span><span class="cls_004"> property on the actual button from the last full example, but instead let's</span></div>
<div style="position:absolute;left:5.00px;top:428.25px" class="cls_004"><span class="cls_004">highlight an extremely common mistake that a lot of developers make. Imagine a situation</span></div>
<div style="position:absolute;left:5.00px;top:446.25px" class="cls_004"><span class="cls_004">where we want to output a value predominantly in one color, but in another color under</span></div>
<div style="position:absolute;left:5.00px;top:464.25px" class="cls_004"><span class="cls_004">certain circumstances. Some developers might try something like this.</span></div>
<div style="position:absolute;left:52.98px;top:487.50px" class="cls_007"><span class="cls_007"><TextBlock Text="{Binding Account.Amount, StringFormat={}{0:C}}"</span></div>
<div style="position:absolute;left:67.97px;top:501.00px" class="cls_007"><span class="cls_007">Foreground="Green"></span></div>
<div style="position:absolute;left:67.97px;top:514.50px" class="cls_007"><span class="cls_007"><TextBlock.Style></span></div>
<div style="position:absolute;left:82.97px;top:528.00px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type TextBlock}"></span></div>
<div style="position:absolute;left:97.96px;top:541.50px" class="cls_007"><span class="cls_007"><Style.Triggers></span></div>
<div style="position:absolute;left:112.96px;top:555.00px" class="cls_007"><span class="cls_007"><DataTrigger Binding="{Binding Account.IsOverdrawn}"</span></div>
<div style="position:absolute;left:52.98px;top:568.50px" class="cls_007"><span class="cls_007">Value="True"></span></div>
<div style="position:absolute;left:127.95px;top:582.00px" class="cls_007"><span class="cls_007"><Setter Property="Foreground" Value="Red" /></span></div>
<div style="position:absolute;left:112.96px;top:595.50px" class="cls_007"><span class="cls_007"></DataTrigger></span></div>
<div style="position:absolute;left:97.96px;top:609.00px" class="cls_007"><span class="cls_007"></Style.Triggers></span></div>
<div style="position:absolute;left:82.97px;top:622.50px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:67.97px;top:636.00px" class="cls_007"><span class="cls_007"></TextBlock.Style></span></div>
<div style="position:absolute;left:52.98px;top:649.50px" class="cls_007"><span class="cls_007"></TextBlock></span></div>
<div style="position:absolute;left:5.00px;top:669.75px" class="cls_004"><span class="cls_004">Upon running this example, some might expect this to work and be stumped when it doesn't.</span></div>
<div style="position:absolute;left:5.00px;top:687.75px" class="cls_004"><span class="cls_004">The reason why this doesn't work is because local property settings have a higher value</span></div>
<div style="position:absolute;left:5.00px;top:705.75px" class="cls_004"><span class="cls_004">setting precedence than properties set by style triggers. The solution to correcting this</span></div>
<div style="position:absolute;left:5.00px;top:723.75px" class="cls_004"><span class="cls_004">mistake is to use our new found knowledge of this value setting precedence list and move</span></div>
<div style="position:absolute;left:5.00px;top:741.75px" class="cls_004"><span class="cls_004">the local property setting to a style setter, which has a lower precedence than the trigger.</span></div>
<div style="position:absolute;left:52.98px;top:765.00px" class="cls_007"><span class="cls_007"><TextBlock Text="{Binding Account.Amount, StringFormat={}{0:C}}"></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:121904px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background154.jpg" width=612 height=792></div>
<div style="position:absolute;left:67.97px;top:3.00px" class="cls_007"><span class="cls_007"><TextBlock.Style></span></div>
<div style="position:absolute;left:82.97px;top:16.50px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type TextBlock}"></span></div>
<div style="position:absolute;left:97.96px;top:30.00px" class="cls_007"><span class="cls_007"><Setter Property="Foreground" Value="Green" /></span></div>
<div style="position:absolute;left:97.96px;top:43.50px" class="cls_007"><span class="cls_007"><Style.Triggers></span></div>
<div style="position:absolute;left:112.96px;top:57.00px" class="cls_007"><span class="cls_007"><DataTrigger Binding="{Binding Account.IsOverdrawn}"</span></div>
<div style="position:absolute;left:52.98px;top:70.50px" class="cls_007"><span class="cls_007">Value="True"></span></div>
<div style="position:absolute;left:127.95px;top:84.00px" class="cls_007"><span class="cls_007"><Setter Property="Foreground" Value="Red" /></span></div>
<div style="position:absolute;left:112.96px;top:97.50px" class="cls_007"><span class="cls_007"></DataTrigger></span></div>
<div style="position:absolute;left:97.96px;top:111.00px" class="cls_007"><span class="cls_007"></Style.Triggers></span></div>
<div style="position:absolute;left:82.97px;top:124.50px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:67.97px;top:138.00px" class="cls_007"><span class="cls_007"></TextBlock.Style></span></div>
<div style="position:absolute;left:52.98px;top:151.50px" class="cls_007"><span class="cls_007"></TextBlock></span></div>
<div style="position:absolute;left:5.00px;top:171.75px" class="cls_004"><span class="cls_004">Now, the </span><span class="cls_007">TextBlock.Foreground</span><span class="cls_004"> property will be set to green from the style setter and</span></div>
<div style="position:absolute;left:5.00px;top:189.75px" class="cls_004"><span class="cls_004">overridden by the trigger when the condition is true, as expected. Let's continue up the list</span></div>
<div style="position:absolute;left:5.00px;top:207.75px" class="cls_004"><span class="cls_004">to position two. In the penultimate position, we have property values that are set by</span></div>
<div style="position:absolute;left:5.00px;top:225.75px" class="cls_004"><span class="cls_004">animations. A very simple example can demonstrate this nicely for us.</span></div>
<div style="position:absolute;left:52.98px;top:249.00px" class="cls_007"><span class="cls_007"><Rectangle Width="300" Height="300" Fill="Orange"></span></div>
<div style="position:absolute;left:67.97px;top:262.50px" class="cls_007"><span class="cls_007"><Rectangle.Triggers></span></div>
<div style="position:absolute;left:82.97px;top:276.00px" class="cls_007"><span class="cls_007"><EventTrigger RoutedEvent="Loaded"></span></div>
<div style="position:absolute;left:97.96px;top:289.50px" class="cls_007"><span class="cls_007"><BeginStoryboard></span></div>
<div style="position:absolute;left:112.96px;top:303.00px" class="cls_007"><span class="cls_007"><Storyboard Storyboard.TargetProperty="Width"></span></div>
<div style="position:absolute;left:127.95px;top:316.50px" class="cls_007"><span class="cls_007"><DoubleAnimation Duration="0:0:1" To="50"</span></div>
<div style="position:absolute;left:52.98px;top:330.00px" class="cls_007"><span class="cls_007">AutoReverse="True"</span></div>
<div style="position:absolute;left:142.94px;top:343.50px" class="cls_007"><span class="cls_007">RepeatBehavior="Forever" /></span></div>
<div style="position:absolute;left:112.96px;top:357.00px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:97.96px;top:370.50px" class="cls_007"><span class="cls_007"></BeginStoryboard></span></div>
<div style="position:absolute;left:82.97px;top:384.00px" class="cls_007"><span class="cls_007"></EventTrigger></span></div>
<div style="position:absolute;left:67.97px;top:397.50px" class="cls_007"><span class="cls_007"></Rectangle.Triggers></span></div>
<div style="position:absolute;left:52.98px;top:411.00px" class="cls_007"><span class="cls_007"></Rectangle></span></div>
<div style="position:absolute;left:5.00px;top:431.25px" class="cls_004"><span class="cls_004">In this example, the animation overrides the locally set value of the </span><span class="cls_007">Width</span><span class="cls_004"> property and the</span></div>
<div style="position:absolute;left:5.00px;top:449.25px" class="cls_004"><span class="cls_004">rectangle grows and shrinks as planned. If we think logically about this, then it is clear that</span></div>
<div style="position:absolute;left:5.00px;top:467.25px" class="cls_004"><span class="cls_004">the animation system had to feature at a very high position on the property setting</span></div>
<div style="position:absolute;left:5.00px;top:485.25px" class="cls_004"><span class="cls_004">precedence list. Otherwise, if it was much lower down the list, we wouldn't be able to</span></div>
<div style="position:absolute;left:5.00px;top:503.25px" class="cls_004"><span class="cls_004">animate anything.</span></div>
<div style="position:absolute;left:5.00px;top:521.25px" class="cls_004"><span class="cls_004">However, properties that are set by animations are at number two of the list, which means</span></div>
<div style="position:absolute;left:5.00px;top:539.25px" class="cls_004"><span class="cls_004">that there is one place that a property can be set that will override even values set by</span></div>
<div style="position:absolute;left:5.00px;top:557.25px" class="cls_004"><span class="cls_004">animations. At number one on the list of Dependency Property Setting Precedence, with the</span></div>
<div style="position:absolute;left:5.00px;top:575.25px" class="cls_004"><span class="cls_004">absolutely highest priority setting, is the property coercion system that we discussed in the</span></div>
<div style="position:absolute;left:5.00px;top:593.25px" class="cls_006"><span class="cls_006">Dependency Properties</span><span class="cls_004"> section.</span></div>
<div style="position:absolute;left:5.00px;top:612.00px" class="cls_004"><span class="cls_004">This could only really happen if we built a custom control that animated a custom</span></div>
<div style="position:absolute;left:5.00px;top:630.00px" class="cls_004"><span class="cls_004">Dependency Property that had particular requirements placed upon it, such as specifying</span></div>
<div style="position:absolute;left:5.00px;top:648.00px" class="cls_004"><span class="cls_004">that it should have a certain maximum or minimum value. In this case, we could enforce</span></div>
<div style="position:absolute;left:5.00px;top:666.00px" class="cls_004"><span class="cls_004">these rules in a </span><span class="cls_007">CoerceValueCallback</span><span class="cls_004"> handler that is attached to the Dependency Property.</span></div>
<div style="position:absolute;left:5.00px;top:684.00px" class="cls_004"><span class="cls_004">If we had these requirements that were enforced by the property coercion system, yet</span></div>
<div style="position:absolute;left:5.00px;top:702.00px" class="cls_004"><span class="cls_004">wanted to animate them in the UI, it again makes perfect sense that we would want our</span></div>
<div style="position:absolute;left:5.00px;top:720.00px" class="cls_004"><span class="cls_004">coerced values to override the values set by the animation. In this way, we could rest</span></div>
<div style="position:absolute;left:5.00px;top:738.00px" class="cls_004"><span class="cls_004">assured that our coerced property values will remain within the bounds that we set for them</span></div>
<div style="position:absolute;left:5.00px;top:756.00px" class="cls_004"><span class="cls_004">at all times.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:122706px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background155.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_008"><span class="cls_008">Data templates</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">We've already seen a number of simple examples of the </span><span class="cls_007">DataTemplate</span><span class="cls_004">, but they are such</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">an important part of WPF that we're going to have a much more thorough look at them now.</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">In short, we use a </span><span class="cls_007">DataTemplate</span><span class="cls_004"> to define how we want particular data objects to be</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">rendered in the UI</span><span class="cls_006">.</span></div>
<div style="position:absolute;left:5.00px;top:112.50px" class="cls_004"><span class="cls_004">If we were to data bind a particular type of object to a UI control without providing a</span></div>
<div style="position:absolute;left:5.00px;top:130.50px" class="cls_007"><span class="cls_007">DataTemplate</span><span class="cls_004"> for it, the WPF Framework would not know how to display it. In these cases,</span></div>
<div style="position:absolute;left:5.00px;top:148.50px" class="cls_004"><span class="cls_004">the best job that it can do is to display a string representation of it.</span></div>
<div style="position:absolute;left:52.98px;top:171.75px" class="cls_007"><span class="cls_007"><ItemsControl ItemsSource="{Binding Users}" /></span></div>
<div style="position:absolute;left:5.00px;top:192.00px" class="cls_004"><span class="cls_004">It achieves this by calling the </span><span class="cls_007">object.ToString</span><span class="cls_004"> method on the data object and setting that</span></div>
<div style="position:absolute;left:5.00px;top:210.00px" class="cls_004"><span class="cls_004">value to the </span><span class="cls_007">Text</span><span class="cls_004"> property of a </span><span class="cls_007">TextBlock</span><span class="cls_004">, which it uses to display the object. If this method</span></div>
<div style="position:absolute;left:5.00px;top:228.00px" class="cls_004"><span class="cls_004">has not been overridden in the object's class, this will result in the name of the type of the</span></div>
<div style="position:absolute;left:5.00px;top:246.00px" class="cls_004"><span class="cls_004">object being displayed in its place.</span></div>
<div style="position:absolute;left:5.00px;top:348.75px" class="cls_004"><span class="cls_004">Knowing that the WPF Framework will call the </span><span class="cls_007">ToString</span><span class="cls_004"> method on our data objects before</span></div>
<div style="position:absolute;left:5.00px;top:366.75px" class="cls_004"><span class="cls_004">displaying them enables us to take a shortcut, or a simple alternative to defining a</span></div>
<div style="position:absolute;left:5.00px;top:384.75px" class="cls_007"><span class="cls_007">DataTemplate</span><span class="cls_004">, if we only need a textual output in the UI. Therefore, it is always a good idea</span></div>
<div style="position:absolute;left:5.00px;top:402.75px" class="cls_004"><span class="cls_004">for us to override the </span><span class="cls_007">object.ToString</span><span class="cls_004"> method to output some meaningful display.</span></div>
<div style="position:absolute;left:52.98px;top:426.00px" class="cls_007"><span class="cls_007">public override string ToString()</span></div>
<div style="position:absolute;left:52.98px;top:439.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:453.00px" class="cls_007"><span class="cls_007">return Name;</span></div>
<div style="position:absolute;left:52.98px;top:466.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:486.75px" class="cls_004"><span class="cls_004">This will result in the following output:</span></div>
<div style="position:absolute;left:5.00px;top:587.25px" class="cls_004"><span class="cls_004">Note that Visual Studio IntelliSense also calls the </span><span class="cls_007">ToString</span><span class="cls_004"> method on our data objects</span></div>
<div style="position:absolute;left:5.00px;top:605.25px" class="cls_004"><span class="cls_004">before displaying them, so the benefit of providing a custom implementation for it is</span></div>
<div style="position:absolute;left:5.00px;top:623.25px" class="cls_004"><span class="cls_004">doubled. As such, we often add an abstract method into our base class to ensure that all</span></div>
<div style="position:absolute;left:5.00px;top:641.25px" class="cls_004"><span class="cls_004">derived classes will implement this method.</span></div>
<div style="position:absolute;left:52.98px;top:664.50px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.DataModels</span></div>
<div style="position:absolute;left:52.98px;top:678.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:691.50px" class="cls_007"><span class="cls_007">public abstract class BaseDataModel : INotifyPropertyChanged</span></div>
<div style="position:absolute;left:67.97px;top:705.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:745.50px" class="cls_007"><span class="cls_007">public abstract override string ToString();</span></div>
<div style="position:absolute;left:67.97px;top:759.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:772.50px" class="cls_007"><span class="cls_007">}</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:123508px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background156.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:9.75px" class="cls_004"><span class="cls_004">Returning to the topic of data templates now, let's first take a look at a better example for</span></div>
<div style="position:absolute;left:5.00px;top:27.75px" class="cls_004"><span class="cls_004">our </span><span class="cls_007">User</span><span class="cls_004"> objects and then investigate where we can declare our data templates.</span></div>
<div style="position:absolute;left:52.98px;top:51.00px" class="cls_007"><span class="cls_007"><DataTemplate x:Key="UserTemplate" DataType="{x:Type</span></div>
<div style="position:absolute;left:52.98px;top:64.50px" class="cls_007"><span class="cls_007">DataModels:User}"></span></div>
<div style="position:absolute;left:67.97px;top:78.00px" class="cls_007"><span class="cls_007"><Border BorderBrush="Black" BorderThickness="1" CornerRadius="5"</span></div>
<div style="position:absolute;left:82.97px;top:91.50px" class="cls_007"><span class="cls_007">Padding="5" Margin="0,0,0,5"></span></div>
<div style="position:absolute;left:82.97px;top:105.00px" class="cls_007"><span class="cls_007"><StackPanel Orientation="Horizontal"></span></div>
<div style="position:absolute;left:97.96px;top:118.50px" class="cls_007"><span class="cls_007"><TextBlock Text="{Binding Name}" Margin="0,0,3,0" /></span></div>
<div style="position:absolute;left:97.96px;top:132.00px" class="cls_007"><span class="cls_007"><TextBlock Text="{Binding Age, StringFormat={}({0})}" /></span></div>
<div style="position:absolute;left:82.97px;top:145.50px" class="cls_007"><span class="cls_007"></StackPanel></span></div>
<div style="position:absolute;left:67.97px;top:159.00px" class="cls_007"><span class="cls_007"></Border></span></div>
<div style="position:absolute;left:52.98px;top:172.50px" class="cls_007"><span class="cls_007"></DataTemplate></span></div>
<div style="position:absolute;left:5.00px;top:205.50px" class="cls_004"><span class="cls_004">In this example, we simply output the user's name in one </span><span class="cls_007">TextBlock</span><span class="cls_004"> and their age in</span></div>
<div style="position:absolute;left:5.00px;top:223.50px" class="cls_004"><span class="cls_004">another. Note the use of the </span><span class="cls_007">StringFormat</span><span class="cls_004"> property to surround the age in brackets in the</span></div>
<div style="position:absolute;left:5.00px;top:241.50px" class="cls_004"><span class="cls_004">output. Let's now see how this </span><span class="cls_007">DataTemplate</span><span class="cls_004"> renders our </span><span class="cls_007">User</span><span class="cls_004"> objects.</span></div>
<div style="position:absolute;left:5.00px;top:378.00px" class="cls_004"><span class="cls_004">Primarily, we can declare our data templates in one of four main places. The first is in line</span></div>
<div style="position:absolute;left:5.00px;top:396.00px" class="cls_004"><span class="cls_004">with the control that the related data object or objects will be displayed in. We have two</span></div>
<div style="position:absolute;left:5.00px;top:414.00px" class="cls_004"><span class="cls_004">main options for this too, depending on the number of data objects that we have to display.</span></div>
<div style="position:absolute;left:5.00px;top:432.00px" class="cls_004"><span class="cls_004">If we have a single object to display, we can utilize the </span><span class="cls_007">ContentControl</span><span class="cls_004"> element to display it</span></div>
<div style="position:absolute;left:5.00px;top:450.00px" class="cls_004"><span class="cls_004">and the </span><span class="cls_007">ContentControl.ContentTemplate</span><span class="cls_004"> property to define the </span><span class="cls_007">DataTemplate</span><span class="cls_004"> element</span></div>
<div style="position:absolute;left:5.00px;top:468.00px" class="cls_004"><span class="cls_004">that it should use to render the data object.</span></div>
<div style="position:absolute;left:52.98px;top:491.25px" class="cls_007"><span class="cls_007"><ContentControl Content="{Binding Users[0]}"></span></div>
<div style="position:absolute;left:67.97px;top:504.75px" class="cls_007"><span class="cls_007"><ContentControl.ContentTemplate></span></div>
<div style="position:absolute;left:82.97px;top:518.25px" class="cls_007"><span class="cls_007"><DataTemplate DataType="{x:Type DataModels:User}"></span></div>
<div style="position:absolute;left:82.97px;top:545.25px" class="cls_007"><span class="cls_007"></DataTemplate></span></div>
<div style="position:absolute;left:67.97px;top:558.75px" class="cls_007"><span class="cls_007"></ContentControl.ContentTemplate></span></div>
<div style="position:absolute;left:52.98px;top:572.25px" class="cls_007"><span class="cls_007"></ContentControl></span></div>
<div style="position:absolute;left:5.00px;top:592.50px" class="cls_004"><span class="cls_004">Similarly, in a collection control, or </span><span class="cls_007">ItemsControl</span><span class="cls_004">, such as the </span><span class="cls_007">ListBox</span><span class="cls_004"> control, we can</span></div>
<div style="position:absolute;left:5.00px;top:610.50px" class="cls_004"><span class="cls_004">declare our </span><span class="cls_007">DataTemplate</span><span class="cls_004"> directly in the </span><span class="cls_007">ItemTemplate</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:52.98px;top:633.75px" class="cls_007"><span class="cls_007"><ListBox ItemsSource="{Binding Users}"></span></div>
<div style="position:absolute;left:67.97px;top:647.25px" class="cls_007"><span class="cls_007"><ListBox.ItemTemplate></span></div>
<div style="position:absolute;left:82.97px;top:660.75px" class="cls_007"><span class="cls_007"><DataTemplate DataType="{x:Type DataModels:User}"></span></div>
<div style="position:absolute;left:82.97px;top:687.75px" class="cls_007"><span class="cls_007"></DataTemplate></span></div>
<div style="position:absolute;left:67.97px;top:701.25px" class="cls_007"><span class="cls_007"></ListBox.ItemTemplate></span></div>
<div style="position:absolute;left:52.98px;top:714.75px" class="cls_007"><span class="cls_007"></ListBox></span></div>
<div style="position:absolute;left:5.00px;top:735.00px" class="cls_004"><span class="cls_004">The next place that we can declare our data templates is in the </span><span class="cls_007">Resources</span><span class="cls_004"> section of the</span></div>
<div style="position:absolute;left:5.00px;top:753.00px" class="cls_004"><span class="cls_004">control that will display the data object or objects. Here is our </span><span class="cls_007">ContentControl</span><span class="cls_004"> now.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:124310px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background157.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:9.00px" class="cls_007"><span class="cls_007"><ContentControl Content="{Binding Users[0]}"</span></div>
<div style="position:absolute;left:67.97px;top:22.50px" class="cls_007"><span class="cls_007">ContentTemplate="{StaticResource UserTemplate}"></span></div>
<div style="position:absolute;left:67.97px;top:36.00px" class="cls_007"><span class="cls_007"><ContentControl.Resources></span></div>
<div style="position:absolute;left:82.97px;top:49.50px" class="cls_007"><span class="cls_007"><DataTemplate x:Key="UserTemplate" DataType="{x:Type</span></div>
<div style="position:absolute;left:52.98px;top:63.00px" class="cls_007"><span class="cls_007">DataModels:User}"></span></div>
<div style="position:absolute;left:82.97px;top:90.00px" class="cls_007"><span class="cls_007"></DataTemplate></span></div>
<div style="position:absolute;left:67.97px;top:103.50px" class="cls_007"><span class="cls_007"></ContentControl.Resources></span></div>
<div style="position:absolute;left:52.98px;top:117.00px" class="cls_007"><span class="cls_007"></ContentControl></span></div>
<div style="position:absolute;left:5.00px;top:137.25px" class="cls_004"><span class="cls_004">The next place that we can declare our data templates is in the </span><span class="cls_007">Resources</span><span class="cls_004"> section of the</span></div>
<div style="position:absolute;left:5.00px;top:155.25px" class="cls_007"><span class="cls_007">Window</span><span class="cls_004"> or </span><span class="cls_007">UserControl</span><span class="cls_004"> that contains the control that displays the data objects. If we have</span></div>
<div style="position:absolute;left:5.00px;top:173.25px" class="cls_004"><span class="cls_004">multiple data objects, then we can set our data template to the resource, like this.</span></div>
<div style="position:absolute;left:52.98px;top:196.50px" class="cls_007"><span class="cls_007"><UserControl.Resources></span></div>
<div style="position:absolute;left:67.97px;top:210.00px" class="cls_007"><span class="cls_007"><DataTemplate x:Key="UserTemplate" DataType="{x:Type</span></div>
<div style="position:absolute;left:52.98px;top:223.50px" class="cls_007"><span class="cls_007">DataModels:User}"></span></div>
<div style="position:absolute;left:67.97px;top:250.50px" class="cls_007"><span class="cls_007"></DataTemplate></span></div>
<div style="position:absolute;left:52.98px;top:264.00px" class="cls_007"><span class="cls_007"></UserControl.Resources></span></div>
<div style="position:absolute;left:52.98px;top:277.50px" class="cls_007"><span class="cls_007"><ListBox ItemsSource="{Binding Users}"</span></div>
<div style="position:absolute;left:67.97px;top:291.00px" class="cls_007"><span class="cls_007">ItemTemplate="{StaticResource UserTemplate}" /></span></div>
<div style="position:absolute;left:5.00px;top:311.25px" class="cls_004"><span class="cls_004">The last place that we can define our data templates is in the </span><span class="cls_007">Application.Resources</span></div>
<div style="position:absolute;left:5.00px;top:329.25px" class="cls_004"><span class="cls_004">section of the </span><span class="cls_007">App.xaml</span><span class="cls_004"> file. When the WPF Framework searches for a data template for a</span></div>
<div style="position:absolute;left:5.00px;top:347.25px" class="cls_004"><span class="cls_004">data object, it first searches the local </span><span class="cls_007">Resources</span><span class="cls_004"> section of the control that is applying the</span></div>
<div style="position:absolute;left:5.00px;top:365.25px" class="cls_004"><span class="cls_004">template.</span></div>
<div style="position:absolute;left:5.00px;top:383.25px" class="cls_004"><span class="cls_004">If it finds no match for the type of the data object, it then searches the </span><span class="cls_007">Resources</span><span class="cls_004"> collection</span></div>
<div style="position:absolute;left:5.00px;top:401.25px" class="cls_004"><span class="cls_004">of the parent control and then the parent of that control and so on. If it still does not find a</span></div>
<div style="position:absolute;left:5.00px;top:419.25px" class="cls_004"><span class="cls_004">data template with a matching type, then it will search through the </span><span class="cls_007">Application.Resources</span></div>
<div style="position:absolute;left:5.00px;top:437.25px" class="cls_004"><span class="cls_004">section of the </span><span class="cls_007">App.xaml</span><span class="cls_004"> page.</span></div>
<div style="position:absolute;left:5.00px;top:455.25px" class="cls_004"><span class="cls_004">We can use this order of lookup to our advantage. We often declare our default data</span></div>
<div style="position:absolute;left:5.00px;top:473.25px" class="cls_004"><span class="cls_004">templates in the </span><span class="cls_007">Application.Resources</span><span class="cls_004"> section of the </span><span class="cls_007">App.xaml</span><span class="cls_004"> page, as these resources</span></div>
<div style="position:absolute;left:5.00px;top:491.25px" class="cls_004"><span class="cls_004">are available application wide. If we need to override our default data templates, to display</span></div>
<div style="position:absolute;left:5.00px;top:509.25px" class="cls_004"><span class="cls_004">a particular output in a particular View, we can declare a new data template with the same</span></div>
<div style="position:absolute;left:5.00px;top:527.25px" class="cls_007"><span class="cls_007">x:Key</span><span class="cls_004"> directive locally in the View's </span><span class="cls_007">Resources</span><span class="cls_004"> section.</span></div>
<div style="position:absolute;left:5.00px;top:545.25px" class="cls_004"><span class="cls_004">As the local </span><span class="cls_007">Resources</span><span class="cls_004"> section is searched before the application resources, it will use the</span></div>
<div style="position:absolute;left:5.00px;top:563.25px" class="cls_004"><span class="cls_004">locally declared data template instead of the default one. Another way of overriding our</span></div>
<div style="position:absolute;left:5.00px;top:581.25px" class="cls_004"><span class="cls_004">default templates is to declare them without setting their </span><span class="cls_007">x:Key</span><span class="cls_004"> directives.</span></div>
<div style="position:absolute;left:52.98px;top:604.50px" class="cls_007"><span class="cls_007"><DataTemplate DataType="{x:Type DataModels:User}"></span></div>
<div style="position:absolute;left:52.98px;top:631.50px" class="cls_007"><span class="cls_007"></DataTemplate></span></div>
<div style="position:absolute;left:5.00px;top:651.75px" class="cls_004"><span class="cls_004">Resources that are declared in this way are implicitly applied to all data objects of the</span></div>
<div style="position:absolute;left:5.00px;top:669.75px" class="cls_004"><span class="cls_004">appropriate type that do not have a data template explicitly applied. Therefore, in order to</span></div>
<div style="position:absolute;left:5.00px;top:687.75px" class="cls_004"><span class="cls_004">override these default data templates, we can simply declare a new data template and</span></div>
<div style="position:absolute;left:5.00px;top:705.75px" class="cls_004"><span class="cls_004">explicitly set it to the relative template property using its </span><span class="cls_007">x:Key</span><span class="cls_004"> directive. Let's now look at</span></div>
<div style="position:absolute;left:5.00px;top:723.75px" class="cls_004"><span class="cls_004">one further way of specifying a data template.</span></div>
<div style="position:absolute;left:5.00px;top:741.01px" class="cls_011"><span class="cls_011">Taking complete control</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:125112px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background158.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">At times, we might want to display different objects of the same type in different ways,</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">depending on the values of their properties. For example, with a collection of objects that</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">represent vehicles, you might want to have different displays for different types of vehicle,</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">as trucks have different specifications to motor boats. The </span><span class="cls_007">DataTemplateSelector</span><span class="cls_004"> class</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">enables us to do just that.</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">When extending the </span><span class="cls_007">DataTemplateSelector</span><span class="cls_004"> class, we can override its single</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_007"><span class="cls_007">SelectTemplate</span><span class="cls_004"> method. In this method, we are provided with both the data object and the</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">data bound object and can select different data templates to return, dependent on the data</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">object's property values.</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">Let's see a very simple example, where we return one of two data templates based on the</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_007"><span class="cls_007">User</span><span class="cls_004">'s age. We'll first need to declare another </span><span class="cls_007">DataTemplate</span><span class="cls_004"> for our </span><span class="cls_007">User</span><span class="cls_004"> type.</span></div>
<div style="position:absolute;left:52.98px;top:207.00px" class="cls_007"><span class="cls_007"><DataTemplate x:Key="InverseUserTemplate"</span></div>
<div style="position:absolute;left:67.97px;top:220.50px" class="cls_007"><span class="cls_007">DataType="{x:Type DataModels:User}"></span></div>
<div style="position:absolute;left:67.97px;top:234.00px" class="cls_007"><span class="cls_007"><Border BorderBrush="White" BorderThickness="1"</span></div>
<div style="position:absolute;left:52.98px;top:247.50px" class="cls_007"><span class="cls_007">Background="Black"</span></div>
<div style="position:absolute;left:82.97px;top:261.00px" class="cls_007"><span class="cls_007">TextElement.Foreground="White" CornerRadius="5"</span></div>
<div style="position:absolute;left:52.98px;top:274.50px" class="cls_007"><span class="cls_007">Padding="8,3,5,5"</span></div>
<div style="position:absolute;left:82.97px;top:288.00px" class="cls_007"><span class="cls_007">Margin="0,0,0,5"></span></div>
<div style="position:absolute;left:82.97px;top:301.50px" class="cls_007"><span class="cls_007"><StackPanel Orientation="Horizontal"></span></div>
<div style="position:absolute;left:97.96px;top:315.00px" class="cls_007"><span class="cls_007"><TextBlock Text="{Binding Name}" Margin="0,0,3,0" /></span></div>
<div style="position:absolute;left:97.96px;top:328.50px" class="cls_007"><span class="cls_007"><TextBlock Text="{Binding Age, StringFormat={}({0})}" /></span></div>
<div style="position:absolute;left:82.97px;top:342.00px" class="cls_007"><span class="cls_007"></StackPanel></span></div>
<div style="position:absolute;left:67.97px;top:355.50px" class="cls_007"><span class="cls_007"></Border></span></div>
<div style="position:absolute;left:52.98px;top:369.00px" class="cls_007"><span class="cls_007"></DataTemplate></span></div>
<div style="position:absolute;left:5.00px;top:389.25px" class="cls_004"><span class="cls_004">In this template, we have simply inverted the colors of the background and foreground from</span></div>
<div style="position:absolute;left:5.00px;top:407.25px" class="cls_004"><span class="cls_004">those in the first template. Let's now see our </span><span class="cls_007">DataTemplateSelector</span><span class="cls_004"> class that will</span></div>
<div style="position:absolute;left:5.00px;top:425.25px" class="cls_004"><span class="cls_004">reference both this and the other </span><span class="cls_007">DataTemplate</span><span class="cls_004"> element.</span></div>
<div style="position:absolute;left:52.98px;top:448.50px" class="cls_007"><span class="cls_007">using System.Windows;</span></div>
<div style="position:absolute;left:52.98px;top:462.00px" class="cls_007"><span class="cls_007">using System.Windows.Controls;</span></div>
<div style="position:absolute;left:52.98px;top:475.50px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.DataModels;</span></div>
<div style="position:absolute;left:52.98px;top:502.50px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.Views.DataTemplateSelectors</span></div>
<div style="position:absolute;left:52.98px;top:516.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:529.50px" class="cls_007"><span class="cls_007">public class UserAgeDataTemplateSelector : DataTemplateSelector</span></div>
<div style="position:absolute;left:67.97px;top:543.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:556.50px" class="cls_007"><span class="cls_007">public override DataTemplate SelectTemplate(object item,</span></div>
<div style="position:absolute;left:97.96px;top:570.00px" class="cls_007"><span class="cls_007">DependencyObject container)</span></div>
<div style="position:absolute;left:82.97px;top:583.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:597.00px" class="cls_007"><span class="cls_007">FrameworkElement element = container as FrameworkElement;</span></div>
<div style="position:absolute;left:97.96px;top:610.50px" class="cls_007"><span class="cls_007">if (element != null && item != null && item is User)</span></div>
<div style="position:absolute;left:97.96px;top:624.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:112.96px;top:637.50px" class="cls_007"><span class="cls_007">User user = (User)item;</span></div>
<div style="position:absolute;left:112.96px;top:651.00px" class="cls_007"><span class="cls_007">if (user.Age < 35) return</span></div>
<div style="position:absolute;left:52.98px;top:678.00px" class="cls_007"><span class="cls_007">(DataTemplate)element.FindResource("InverseUserTemplate");</span></div>
<div style="position:absolute;left:112.96px;top:691.50px" class="cls_007"><span class="cls_007">else return</span></div>
<div style="position:absolute;left:52.98px;top:705.00px" class="cls_007"><span class="cls_007">(DataTemplate)element.FindResource("UserTemplate");</span></div>
<div style="position:absolute;left:97.96px;top:718.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:97.96px;top:732.00px" class="cls_007"><span class="cls_007">return null;</span></div>
<div style="position:absolute;left:82.97px;top:745.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:759.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:772.50px" class="cls_007"><span class="cls_007">}</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:125914px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background159.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:9.75px" class="cls_004"><span class="cls_004">In this example, we perform the standard null checks for the two input parameters and a</span></div>
<div style="position:absolute;left:5.00px;top:27.75px" class="cls_004"><span class="cls_004">further check to ensure that the current data object is of the expected type. If the input</span></div>
<div style="position:absolute;left:5.00px;top:45.75px" class="cls_004"><span class="cls_004">parameters pass the checks, we cast the </span><span class="cls_007">item</span><span class="cls_004"> parameter to a </span><span class="cls_007">User</span><span class="cls_004"> object and use the</span></div>
<div style="position:absolute;left:5.00px;top:63.75px" class="cls_007"><span class="cls_007">FindResource</span><span class="cls_004"> method to return the appropriate data template dependent upon the value of</span></div>
<div style="position:absolute;left:5.00px;top:81.75px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">Age</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:5.00px;top:99.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">FrameworkElement.FindResource</span><span class="cls_004"> method first searches the calling object for the data</span></div>
<div style="position:absolute;left:5.00px;top:117.75px" class="cls_004"><span class="cls_004">template and then it's parent element and so on, up the logical tree. If it doesn't find it in any</span></div>
<div style="position:absolute;left:5.00px;top:135.75px" class="cls_004"><span class="cls_004">parent element in the application window, it then looks through the </span><span class="cls_007">App.xaml</span><span class="cls_004"> file. If it still</span></div>
<div style="position:absolute;left:5.00px;top:153.75px" class="cls_004"><span class="cls_004">does not find it there, it then searches in the themes and system resources.</span></div>
<div style="position:absolute;left:5.00px;top:171.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">container</span><span class="cls_004"> input parameter is used to access the </span><span class="cls_007">FindResource</span><span class="cls_004"> method. Note that it will</span></div>
<div style="position:absolute;left:5.00px;top:189.75px" class="cls_004"><span class="cls_004">typically be of type </span><span class="cls_007">ContentPresenter</span><span class="cls_004"> if we're using a normal collection control, so we could</span></div>
<div style="position:absolute;left:5.00px;top:207.75px" class="cls_004"><span class="cls_004">have cast it to that type in order to access the data templates.</span></div>
<div style="position:absolute;left:5.00px;top:225.75px" class="cls_004"><span class="cls_004">However, the default container could be overridden to use one of the parent classes that</span></div>
<div style="position:absolute;left:5.00px;top:243.75px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">ContentPresenter</span><span class="cls_004"> class is derived from. Therefore, to avoid the possibility of</span></div>
<div style="position:absolute;left:5.00px;top:261.75px" class="cls_004"><span class="cls_004">exceptions, it is safer to cast it to the </span><span class="cls_007">FrameworkElement</span><span class="cls_004"> class that actually declares the</span></div>
<div style="position:absolute;left:5.00px;top:279.75px" class="cls_007"><span class="cls_007">FindResource</span><span class="cls_004"> method.</span></div>
<div style="position:absolute;left:5.00px;top:297.75px" class="cls_004"><span class="cls_004">Let's see how we can use this class now. First, we need to add the XML namespace prefix</span></div>
<div style="position:absolute;left:5.00px;top:315.75px" class="cls_004"><span class="cls_004">for our </span><span class="cls_007">DataTemplateSelectors</span><span class="cls_004"> namespace.</span></div>
<div style="position:absolute;left:52.98px;top:339.00px" class="cls_007"><span class="cls_007">xmlns:DataTemplateSelectors=</span></div>
<div style="position:absolute;left:67.97px;top:352.50px" class="cls_007"><span class="cls_007">"clr-</span></div>
<div style="position:absolute;left:52.98px;top:366.00px" class="cls_007"><span class="cls_007">namespace:CompanyName.ApplicationName.Views.DataTemplateSelectors"</span></div>
<div style="position:absolute;left:5.00px;top:386.25px" class="cls_004"><span class="cls_004">Then we need to add an instance of our </span><span class="cls_007">UserAgeDataTemplateSelector</span><span class="cls_004"> class to a</span></div>
<div style="position:absolute;left:5.00px;top:404.25px" class="cls_007"><span class="cls_007">Resources</span><span class="cls_004"> section.</span></div>
<div style="position:absolute;left:52.98px;top:427.50px" class="cls_007"><span class="cls_007"><DataTemplateSelectors:UserAgeDataTemplateSelector</span></div>
<div style="position:absolute;left:67.97px;top:441.00px" class="cls_007"><span class="cls_007">x:Key="UserAgeDataTemplateSelector" /></span></div>
<div style="position:absolute;left:5.00px;top:461.25px" class="cls_004"><span class="cls_004">Finally, we set our resource selector to the </span><span class="cls_007">ItemTemplateSelector</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:52.98px;top:484.50px" class="cls_007"><span class="cls_007"><ItemsControl ItemsSource="{Binding Users}" Padding="10"</span></div>
<div style="position:absolute;left:67.97px;top:498.00px" class="cls_007"><span class="cls_007">ItemTemplateSelector="{StaticResource</span></div>
<div style="position:absolute;left:52.98px;top:511.50px" class="cls_007"><span class="cls_007">UserAgeDataTemplateSelector}" /></span></div>
<div style="position:absolute;left:5.00px;top:531.75px" class="cls_004"><span class="cls_004">When running the application now, we'll see this new output.</span></div>
<div style="position:absolute;left:5.00px;top:666.75px" class="cls_004"><span class="cls_004">Note that </span><span class="cls_007">DataTemplateSelector</span><span class="cls_004"> classes are typically used with very different templates,</span></div>
<div style="position:absolute;left:5.00px;top:684.75px" class="cls_004"><span class="cls_004">such as those that make up the different editing or viewing modes of a custom control.</span></div>
<div style="position:absolute;left:5.00px;top:702.75px" class="cls_004"><span class="cls_004">Slight differences like those in our simple example can be far easier achieved using style</span></div>
<div style="position:absolute;left:5.00px;top:720.75px" class="cls_004"><span class="cls_004">triggers and we'll find out more about triggers and styles in the next chapter.</span></div>
<div style="position:absolute;left:5.00px;top:738.01px" class="cls_011"><span class="cls_011">Displaying hierarchical data</span></div>
<div style="position:absolute;left:5.00px;top:768.00px" class="cls_004"><span class="cls_004">There is one class in the .NET Framework that extends the </span><span class="cls_007">DataTemplate</span><span class="cls_004"> class in order to</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:126716px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background160.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">support UI controls that extend the </span><span class="cls_007">HeaderedItemsControl</span><span class="cls_004"> class. As it sounds, the</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_007"><span class="cls_007">HeaderedItemsControl</span><span class="cls_004"> class represents a particular kind of </span><span class="cls_007">ItemsControl</span><span class="cls_004"> element that has</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">a header. Examples include the </span><span class="cls_007">MenuItem</span><span class="cls_004">, </span><span class="cls_007">TreeViewItem</span><span class="cls_004"> and </span><span class="cls_007">ToolBar</span><span class="cls_004"> classes.</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">HierarchicalDataTemplate</span><span class="cls_004"> class was created to display hierarchical Data Models. To</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">clarify a little further, a hierarchical data model is a data model that contains a collection</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">property with items of the same type as the parent object. Think of the folder view in the</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">Windows Explorer window; each folder can contain further folders.</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">The main difference between the </span><span class="cls_007">HierarchicalDataTemplate</span><span class="cls_004"> and the </span><span class="cls_007">DataTemplate</span><span class="cls_004"> class is</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">that the </span><span class="cls_007">HierarchicalDataTemplate</span><span class="cls_004"> class has an </span><span class="cls_007">ItemsSource</span><span class="cls_004"> property that we can use to</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">bind the children of each item to.</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">In addition to the </span><span class="cls_007">ItemsSource</span><span class="cls_004"> property, there are a number of other item-related</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">properties, such as the </span><span class="cls_007">ItemContainerStyle</span><span class="cls_004">, </span><span class="cls_007">ItemStringFormat</span><span class="cls_004"> and </span><span class="cls_007">ItemTemplate</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">properties. We'll find out more about what these other properties do in the next chapter, but</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">for now, let's look at an example.</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">There are plenty of </span><span class="cls_007">HierarchicalDataTemplate</span><span class="cls_004"> examples that demonstrate the use of</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_007"><span class="cls_007">TreeViewItem</span><span class="cls_004"> elements to be found online, so for this example, we'll see how we can build</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">an application menu using data binding. First, we'll need a View Model to data bind to each</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_007"><span class="cls_007">MenuItem</span><span class="cls_004"> control. Let's take a look at our </span><span class="cls_007">MenuItemViewModel</span><span class="cls_004"> class.</span></div>
<div style="position:absolute;left:52.98px;top:333.00px" class="cls_007"><span class="cls_007">using System.Collections.ObjectModel;</span></div>
<div style="position:absolute;left:52.98px;top:346.50px" class="cls_007"><span class="cls_007">using System.Windows.Input;</span></div>
<div style="position:absolute;left:52.98px;top:373.50px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.ViewModels</span></div>
<div style="position:absolute;left:52.98px;top:387.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:400.50px" class="cls_007"><span class="cls_007">public class MenuItemViewModel : BaseViewModel</span></div>
<div style="position:absolute;left:67.97px;top:414.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:427.50px" class="cls_007"><span class="cls_007">private string header = string.Empty;</span></div>
<div style="position:absolute;left:82.97px;top:441.00px" class="cls_007"><span class="cls_007">private ICommand command = null;</span></div>
<div style="position:absolute;left:82.97px;top:454.50px" class="cls_007"><span class="cls_007">private ObservableCollection<MenuItemViewModel> menuItems =</span></div>
<div style="position:absolute;left:97.96px;top:468.00px" class="cls_007"><span class="cls_007">new ObservableCollection<MenuItemViewModel>();</span></div>
<div style="position:absolute;left:82.97px;top:495.00px" class="cls_007"><span class="cls_007">public string Header</span></div>
<div style="position:absolute;left:82.97px;top:508.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:522.00px" class="cls_007"><span class="cls_007">get { return header; }</span></div>
<div style="position:absolute;left:97.96px;top:535.50px" class="cls_007"><span class="cls_007">set { if (header != value) { header = value;</span></div>
<div style="position:absolute;left:112.96px;top:549.00px" class="cls_007"><span class="cls_007">NotifyPropertyChanged(); } }</span></div>
<div style="position:absolute;left:82.97px;top:562.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:589.50px" class="cls_007"><span class="cls_007">public ICommand Command</span></div>
<div style="position:absolute;left:82.97px;top:603.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:616.50px" class="cls_007"><span class="cls_007">get { return command; }</span></div>
<div style="position:absolute;left:97.96px;top:630.00px" class="cls_007"><span class="cls_007">set { if (command != value) { command = value;</span></div>
<div style="position:absolute;left:112.96px;top:643.50px" class="cls_007"><span class="cls_007">NotifyPropertyChanged(); } }</span></div>
<div style="position:absolute;left:82.97px;top:657.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:684.00px" class="cls_007"><span class="cls_007">public ObservableCollection<MenuItemViewModel> MenuItems</span></div>
<div style="position:absolute;left:82.97px;top:697.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:711.00px" class="cls_007"><span class="cls_007">get { return menuItems; }</span></div>
<div style="position:absolute;left:97.96px;top:724.50px" class="cls_007"><span class="cls_007">set { if (menuItems != value) { menuItems = value;</span></div>
<div style="position:absolute;left:112.96px;top:738.00px" class="cls_007"><span class="cls_007">NotifyPropertyChanged(); } }</span></div>
<div style="position:absolute;left:82.97px;top:751.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:765.00px" class="cls_007"><span class="cls_007">}</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:127518px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background161.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:3.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:23.25px" class="cls_004"><span class="cls_004">In this simplified example, our View Model only declares three properties to data bind to the</span></div>
<div style="position:absolute;left:5.00px;top:41.25px" class="cls_007"><span class="cls_007">MenuItem</span><span class="cls_004"> control's properties. In a real application, we would typically add further</span></div>
<div style="position:absolute;left:5.00px;top:59.25px" class="cls_004"><span class="cls_004">properties, so that we could define the icon, or maybe the style of each menu item as well.</span></div>
<div style="position:absolute;left:5.00px;top:77.25px" class="cls_004"><span class="cls_004">However, continuing the example with our View Model, let's look at the class that would</span></div>
<div style="position:absolute;left:5.00px;top:95.25px" class="cls_004"><span class="cls_004">declare these View Models.</span></div>
<div style="position:absolute;left:5.00px;top:113.25px" class="cls_004"><span class="cls_004">If an application has a menu control, it would typically reside in the </span><span class="cls_007">MainWindow.xaml</span><span class="cls_004"> file.</span></div>
<div style="position:absolute;left:5.00px;top:131.25px" class="cls_004"><span class="cls_004">Therefore, the data bound </span><span class="cls_007">MenuItemViewModel</span><span class="cls_004"> elements would be declared in the View</span></div>
<div style="position:absolute;left:5.00px;top:149.25px" class="cls_004"><span class="cls_004">Model that is data bound to the data context of that View. Let's look at the required</span></div>
<div style="position:absolute;left:5.00px;top:167.25px" class="cls_004"><span class="cls_004">properties.</span></div>
<div style="position:absolute;left:52.98px;top:190.50px" class="cls_007"><span class="cls_007">private ObservableCollection<MenuItemViewModel> menuItems =</span></div>
<div style="position:absolute;left:67.97px;top:204.00px" class="cls_007"><span class="cls_007">new ObservableCollection<MenuItemViewModel>();</span></div>
<div style="position:absolute;left:52.98px;top:231.00px" class="cls_007"><span class="cls_007">public ObservableCollection<MenuItemViewModel> MenuItems</span></div>
<div style="position:absolute;left:52.98px;top:244.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:258.00px" class="cls_007"><span class="cls_007">get { return menuItems; }</span></div>
<div style="position:absolute;left:67.97px;top:271.50px" class="cls_007"><span class="cls_007">set { if (menuItems != value) { menuItems = value;</span></div>
<div style="position:absolute;left:82.97px;top:285.00px" class="cls_007"><span class="cls_007">NotifyPropertyChanged(); } }</span></div>
<div style="position:absolute;left:52.98px;top:298.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:318.75px" class="cls_004"><span class="cls_004">An alternative to programmatically declaring the various menu item View Models would be</span></div>
<div style="position:absolute;left:5.00px;top:336.75px" class="cls_004"><span class="cls_004">to define the items in an XML file, read it in and generate the items from that at runtime.</span></div>
<div style="position:absolute;left:5.00px;top:354.75px" class="cls_004"><span class="cls_004">However, for the purpose of this simple example, let's just hard code some values to use,</span></div>
<div style="position:absolute;left:5.00px;top:372.75px" class="cls_004"><span class="cls_004">omitting the commands for brevity.</span></div>
<div style="position:absolute;left:52.98px;top:396.00px" class="cls_007"><span class="cls_007">MenuItems.Add(new MenuItemViewModel() { Header = "Users",</span></div>
<div style="position:absolute;left:67.97px;top:409.50px" class="cls_007"><span class="cls_007">MenuItems = new ObservableCollection<MenuItemViewModel>() {</span></div>
<div style="position:absolute;left:67.97px;top:423.00px" class="cls_007"><span class="cls_007">new MenuItemViewModel() { Header = "Details",</span></div>
<div style="position:absolute;left:67.97px;top:436.50px" class="cls_007"><span class="cls_007">MenuItems = new ObservableCollection<MenuItemViewModel>() {</span></div>
<div style="position:absolute;left:67.97px;top:450.00px" class="cls_007"><span class="cls_007">new MenuItemViewModel() { Header = "Banking" },</span></div>
<div style="position:absolute;left:67.97px;top:463.50px" class="cls_007"><span class="cls_007">new MenuItemViewModel() { Header = "Personal" } } },</span></div>
<div style="position:absolute;left:67.97px;top:477.00px" class="cls_007"><span class="cls_007">new MenuItemViewModel() { Header = "Security" } } });</span></div>
<div style="position:absolute;left:52.98px;top:490.50px" class="cls_007"><span class="cls_007">MenuItems.Add(new MenuItemViewModel() { Header = "Administration"</span></div>
<div style="position:absolute;left:52.98px;top:504.00px" class="cls_007"><span class="cls_007">});</span></div>
<div style="position:absolute;left:52.98px;top:517.50px" class="cls_007"><span class="cls_007">MenuItems.Add(new MenuItemViewModel() { Header = "View" });</span></div>
<div style="position:absolute;left:52.98px;top:531.00px" class="cls_007"><span class="cls_007">MenuItems.Add(new MenuItemViewModel() { Header = "Help",</span></div>
<div style="position:absolute;left:67.97px;top:544.50px" class="cls_007"><span class="cls_007">MenuItems = new ObservableCollection<MenuItemViewModel>() {</span></div>
<div style="position:absolute;left:67.97px;top:558.00px" class="cls_007"><span class="cls_007">new MenuItemViewModel() { Header = "About" } } });</span></div>
<div style="position:absolute;left:5.00px;top:578.25px" class="cls_004"><span class="cls_004">While this code is somewhat difficult to read, it is far more compact than declaring each</span></div>
<div style="position:absolute;left:5.00px;top:596.25px" class="cls_004"><span class="cls_004">child item separately and then building up the hierarchy afterwards. The end result is the</span></div>
<div style="position:absolute;left:5.00px;top:614.25px" class="cls_004"><span class="cls_004">same, so let's now see what the required XAML looks like.</span></div>
<div style="position:absolute;left:52.98px;top:637.50px" class="cls_007"><span class="cls_007"><Menu ItemsSource="{Binding MenuItems}" FontSize="14"</span></div>
<div style="position:absolute;left:52.98px;top:651.00px" class="cls_007"><span class="cls_007">Background="White"></span></div>
<div style="position:absolute;left:67.97px;top:664.50px" class="cls_007"><span class="cls_007"><Menu.ItemContainerStyle></span></div>
<div style="position:absolute;left:82.97px;top:678.00px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type MenuItem}"></span></div>
<div style="position:absolute;left:97.96px;top:691.50px" class="cls_007"><span class="cls_007"><Setter Property="Command" Value="{Binding Command}" /></span></div>
<div style="position:absolute;left:82.97px;top:705.00px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:67.97px;top:718.50px" class="cls_007"><span class="cls_007"></Menu.ItemContainerStyle></span></div>
<div style="position:absolute;left:67.97px;top:732.00px" class="cls_007"><span class="cls_007"><Menu.ItemTemplate></span></div>
<div style="position:absolute;left:82.97px;top:745.50px" class="cls_007"><span class="cls_007"><HierarchicalDataTemplate</span></div>
<div style="position:absolute;left:97.96px;top:759.00px" class="cls_007"><span class="cls_007">DataType="{x:Type ViewModels:MenuItemViewModel}"</span></div>
<div style="position:absolute;left:97.96px;top:772.50px" class="cls_007"><span class="cls_007">ItemsSource="{Binding MenuItems}"></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:128320px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background162.jpg" width=612 height=792></div>
<div style="position:absolute;left:97.96px;top:3.00px" class="cls_007"><span class="cls_007"><TextBlock Text="{Binding Header}" /></span></div>
<div style="position:absolute;left:82.97px;top:16.50px" class="cls_007"><span class="cls_007"></HierarchicalDataTemplate></span></div>
<div style="position:absolute;left:67.97px;top:30.00px" class="cls_007"><span class="cls_007"></Menu.ItemTemplate></span></div>
<div style="position:absolute;left:52.98px;top:43.50px" class="cls_007"><span class="cls_007"></Menu></span></div>
<div style="position:absolute;left:5.00px;top:63.75px" class="cls_004"><span class="cls_004">Here, we declare a </span><span class="cls_007">Menu</span><span class="cls_004"> control and data bind our </span><span class="cls_007">MenuItems</span><span class="cls_004"> collection to its </span><span class="cls_007">ItemsSource</span></div>
<div style="position:absolute;left:5.00px;top:81.75px" class="cls_004"><span class="cls_004">property. The </span><span class="cls_007">ItemContainerStyle</span><span class="cls_004"> enables us to define the style of the UI container that</span></div>
<div style="position:absolute;left:5.00px;top:99.75px" class="cls_004"><span class="cls_004">surrounds each of our data items. In this case, that control is a </span><span class="cls_007">MenuItem</span><span class="cls_004"> control.</span></div>
<div style="position:absolute;left:5.00px;top:117.75px" class="cls_004"><span class="cls_004">All we need to do in this style is to bind the </span><span class="cls_007">Command</span><span class="cls_004"> property of our View Model to the</span></div>
<div style="position:absolute;left:5.00px;top:135.75px" class="cls_007"><span class="cls_007">Command</span><span class="cls_004"> property of the menu item. If we had declared any other properties in our View</span></div>
<div style="position:absolute;left:5.00px;top:153.75px" class="cls_004"><span class="cls_004">Model to map to the </span><span class="cls_007">MenuItem</span><span class="cls_004"> class properties, then this style would be the place to data</span></div>
<div style="position:absolute;left:5.00px;top:171.75px" class="cls_004"><span class="cls_004">bind them.</span></div>
<div style="position:absolute;left:5.00px;top:189.75px" class="cls_004"><span class="cls_004">As discussed earlier, the </span><span class="cls_007">ItemTemplate</span><span class="cls_004"> property enables us to provide a data template, or</span></div>
<div style="position:absolute;left:5.00px;top:207.75px" class="cls_004"><span class="cls_004">in this case, our </span><span class="cls_007">HierarchicalDataTemplate</span><span class="cls_004"> element, that will define how each item will be</span></div>
<div style="position:absolute;left:5.00px;top:225.75px" class="cls_004"><span class="cls_004">rendered. In the template declaration, we state the type of our data items and specify the</span></div>
<div style="position:absolute;left:5.00px;top:243.75px" class="cls_004"><span class="cls_004">collection property that contains the child items.</span></div>
<div style="position:absolute;left:5.00px;top:261.75px" class="cls_004"><span class="cls_004">Inside the template, we simply output the value of the </span><span class="cls_007">Header</span><span class="cls_004"> property in a </span><span class="cls_007">TextBlock</span></div>
<div style="position:absolute;left:5.00px;top:279.75px" class="cls_004"><span class="cls_004">element. This will represent the name of each menu item. Let's see what this will all look</span></div>
<div style="position:absolute;left:5.00px;top:297.75px" class="cls_004"><span class="cls_004">like when the application is running now.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:129122px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background163.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_008"><span class="cls_008">Data binding to enumeration collections</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">We've already seen a number of examples of data binding to enumeration instances. We've</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">seen converters that we can use to convert our enumeration values and Extension methods</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">that we can use to extract additional information from each member. Earlier in this chapter,</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">we even saw a full but basic example using our </span><span class="cls_007">BitRate</span><span class="cls_004"> enumeration. Now, with our new-</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">found knowledge, let's see how we can improve that earlier example.</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">As noted, in the previous example, we manually declared a </span><span class="cls_007">RadioButton</span><span class="cls_004"> control for each of</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">our enumerations. While that is fine for our three member enumeration, it wouldn't make so</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">much sense to use this method if we had a large number of members. Instead, let's think</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">about how we could use a </span><span class="cls_007">DataTemplate</span><span class="cls_004"> to declare how each member should be rendered.</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">Let's remind ourselves how we declared each </span><span class="cls_007">RadioButton</span><span class="cls_004"> in the previous example.</span></div>
<div style="position:absolute;left:52.98px;top:225.00px" class="cls_007"><span class="cls_007"><RadioButton Content="16 bits" IsChecked="{Binding BitRate,</span></div>
<div style="position:absolute;left:67.97px;top:238.50px" class="cls_007"><span class="cls_007">Converter={StaticResource EnumToBoolConverter},</span></div>
<div style="position:absolute;left:67.97px;top:252.00px" class="cls_007"><span class="cls_007">ConverterParameter=Sixteen}" VerticalContentAlignment="Center" /></span></div>
<div style="position:absolute;left:5.00px;top:272.25px" class="cls_004"><span class="cls_004">The first thing that we notice is the hard coded </span><span class="cls_007">Content</span><span class="cls_004"> value. Obviously, we can't do this in</span></div>
<div style="position:absolute;left:5.00px;top:290.25px" class="cls_004"><span class="cls_004">a </span><span class="cls_007">DataTemplate</span><span class="cls_004">, otherwise every member would be given the same label. This is a perfect</span></div>
<div style="position:absolute;left:5.00px;top:308.25px" class="cls_004"><span class="cls_004">place for us to use the </span><span class="cls_007">EnumToDescriptionStringConverter</span><span class="cls_004"> converter that we created</span></div>
<div style="position:absolute;left:5.00px;top:326.25px" class="cls_004"><span class="cls_004">earlier, so let's update that now.</span></div>
<div style="position:absolute;left:52.98px;top:349.50px" class="cls_007"><span class="cls_007"><UserControl.Resources></span></div>
<div style="position:absolute;left:67.97px;top:376.50px" class="cls_007"><span class="cls_007"><Converters:EnumToDescriptionStringConverter</span></div>
<div style="position:absolute;left:82.97px;top:390.00px" class="cls_007"><span class="cls_007">x:Key="EnumToDescriptionStringConverter" /></span></div>
<div style="position:absolute;left:52.98px;top:417.00px" class="cls_007"><span class="cls_007"></UserControl.Resources></span></div>
<div style="position:absolute;left:52.98px;top:444.00px" class="cls_007"><span class="cls_007"><RadioButton Content="{Binding .,</span></div>
<div style="position:absolute;left:67.97px;top:457.50px" class="cls_007"><span class="cls_007">Converter={StaticResource EnumToDescriptionStringConverter}}"</span></div>
<div style="position:absolute;left:67.97px;top:471.00px" class="cls_007"><span class="cls_007">IsChecked="{Binding BitRate,</span></div>
<div style="position:absolute;left:67.97px;top:484.50px" class="cls_007"><span class="cls_007">Converter={StaticResource EnumToBoolConverter},</span></div>
<div style="position:absolute;left:67.97px;top:498.00px" class="cls_007"><span class="cls_007">ConverterParameter=Sixteen}" VerticalContentAlignment="Center" /></span></div>
<div style="position:absolute;left:5.00px;top:531.00px" class="cls_004"><span class="cls_004">Next, we see that we have also hard coded the </span><span class="cls_007">Sixteen</span><span class="cls_004"> enumeration member to the</span></div>
<div style="position:absolute;left:5.00px;top:549.00px" class="cls_007"><span class="cls_007">ConverterParameter</span><span class="cls_004"> property, so we'll need to change that in our data template too. Our</span></div>
<div style="position:absolute;left:5.00px;top:567.00px" class="cls_004"><span class="cls_004">first attempt might be to simply data bind the whole data context from the data template,</span></div>
<div style="position:absolute;left:5.00px;top:585.00px" class="cls_004"><span class="cls_004">which in our case, is one of the enumeration instances.</span></div>
<div style="position:absolute;left:52.98px;top:608.25px" class="cls_007"><span class="cls_007"><RadioButton Content="{Binding .,</span></div>
<div style="position:absolute;left:67.97px;top:621.75px" class="cls_007"><span class="cls_007">Converter={StaticResource EnumToDescriptionStringConverter}}"</span></div>
<div style="position:absolute;left:67.97px;top:635.25px" class="cls_007"><span class="cls_007">IsChecked="{Binding BitRate,</span></div>
<div style="position:absolute;left:67.97px;top:648.75px" class="cls_007"><span class="cls_007">Converter={StaticResource EnumToBoolConverter},</span></div>
<div style="position:absolute;left:67.97px;top:662.25px" class="cls_007"><span class="cls_007">ConverterParameter={Binding}}" VerticalContentAlignment="Center"</span></div>
<div style="position:absolute;left:52.98px;top:675.75px" class="cls_007"><span class="cls_007">/></span></div>
<div style="position:absolute;left:5.00px;top:696.00px" class="cls_004"><span class="cls_004">However, if we do this and run the application, we will receive the following exception.</span></div>
<div style="position:absolute;left:52.98px;top:719.25px" class="cls_009"><span class="cls_009">A 'Binding' cannot be set on the 'ConverterParameter' property of</span></div>
<div style="position:absolute;left:52.98px;top:733.50px" class="cls_009"><span class="cls_009">type 'Binding'. A 'Binding' can only be set on a DependencyProperty</span></div>
<div style="position:absolute;left:52.98px;top:747.75px" class="cls_009"><span class="cls_009">of a DependencyObject.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:129924px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background164.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">Unfortunately, we cannot data bind to the </span><span class="cls_007">ConverterParameter</span><span class="cls_004"> property, as it was not</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">declared as a Dependency Property. As we cannot data bind to this property from within</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">our data template and no longer use the </span><span class="cls_007">EnumToBoolConverter</span><span class="cls_004"> class to specify the selected</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">enumeration instance, this will complicate our example somewhat.</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">One trick that we can use is to utilize the </span><span class="cls_007">SelectedItem</span><span class="cls_004"> property of the </span><span class="cls_007">ListBox</span><span class="cls_004"> </span><span class="cls_007">Item</span><span class="cls_004"> class</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">to hold the value of our selected enumeration member instead. We can achieve this by data</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">binding this property to the </span><span class="cls_007">IsChecked</span><span class="cls_004"> property of each </span><span class="cls_007">RadioButton</span><span class="cls_004"> using a</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_007"><span class="cls_007">RelativeSource.FindAncestor</span><span class="cls_004"> binding in our </span><span class="cls_007">DataTemplate</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:52.98px;top:153.00px" class="cls_007"><span class="cls_007"><RadioButton Content="{Binding .,</span></div>
<div style="position:absolute;left:67.97px;top:166.50px" class="cls_007"><span class="cls_007">Converter={StaticResource EnumToDescriptionStringConverter}}"</span></div>
<div style="position:absolute;left:67.97px;top:180.00px" class="cls_007"><span class="cls_007">IsChecked="{Binding IsSelected,</span></div>
<div style="position:absolute;left:67.97px;top:193.50px" class="cls_007"><span class="cls_007">RelativeSource={RelativeSource AncestorType={x:Type</span></div>
<div style="position:absolute;left:52.98px;top:207.00px" class="cls_007"><span class="cls_007">ListBoxItem}},</span></div>
<div style="position:absolute;left:67.97px;top:220.50px" class="cls_007"><span class="cls_007">FallbackValue=False}" VerticalContentAlignment="Center" /></span></div>
<div style="position:absolute;left:5.00px;top:240.75px" class="cls_004"><span class="cls_004">Note that each data item in a collection control will be implicitly wrapped in a UI container</span></div>
<div style="position:absolute;left:5.00px;top:258.75px" class="cls_004"><span class="cls_004">element. In our case, we'll use a </span><span class="cls_007">ListBox</span><span class="cls_004"> control and so our enumeration instances will be</span></div>
<div style="position:absolute;left:5.00px;top:276.75px" class="cls_004"><span class="cls_004">wrapped in </span><span class="cls_007">ListBox</span><span class="cls_004"> </span><span class="cls_007">Item</span><span class="cls_004"> elements, but if we had chosen a </span><span class="cls_007">ComboBox</span><span class="cls_004"> for example, then our</span></div>
<div style="position:absolute;left:5.00px;top:294.75px" class="cls_004"><span class="cls_004">items' containers would be </span><span class="cls_007">ComboBoxItem</span><span class="cls_004"> elements. We'll find out more about this in the</span></div>
<div style="position:absolute;left:5.00px;top:312.75px" class="cls_004"><span class="cls_004">next chapter, but for now, let's continue looking at this example.</span></div>
<div style="position:absolute;left:5.00px;top:330.75px" class="cls_004"><span class="cls_004">So, now we have data bound the </span><span class="cls_007">Content</span><span class="cls_004"> property of the </span><span class="cls_007">RadioButton</span><span class="cls_004"> to the description of</span></div>
<div style="position:absolute;left:5.00px;top:348.75px" class="cls_004"><span class="cls_004">each member from the </span><span class="cls_007">DescriptionAttribute</span><span class="cls_004"> attribute declared in the enumeration and the</span></div>
<div style="position:absolute;left:5.00px;top:366.75px" class="cls_007"><span class="cls_007">IsChecked</span><span class="cls_004"> property to the </span><span class="cls_007">IsSelected</span><span class="cls_004"> property of the </span><span class="cls_007">ListBox</span><span class="cls_004"> </span><span class="cls_007">Item</span><span class="cls_004"> element. However, we</span></div>
<div style="position:absolute;left:5.00px;top:384.75px" class="cls_004"><span class="cls_004">have lost the connection to our selected enumeration property from the View Model.</span></div>
<div style="position:absolute;left:5.00px;top:402.75px" class="cls_004"><span class="cls_004">In order to restore this connection, we can data bind the </span><span class="cls_007">BitRate</span><span class="cls_004"> property to the</span></div>
<div style="position:absolute;left:5.00px;top:420.75px" class="cls_007"><span class="cls_007">SelectedItem</span><span class="cls_004"> property of the </span><span class="cls_007">ListBox</span><span class="cls_004"> control. The WPF Framework implicitly connects this</span></div>
<div style="position:absolute;left:5.00px;top:438.75px" class="cls_004"><span class="cls_004">property with the </span><span class="cls_007">IsSelected</span><span class="cls_004"> property of each </span><span class="cls_007">ListBox</span><span class="cls_004"> </span><span class="cls_007">Item</span><span class="cls_004"> element and so our connection</span></div>
<div style="position:absolute;left:5.00px;top:456.75px" class="cls_004"><span class="cls_004">between the </span><span class="cls_007">BitRate</span><span class="cls_004"> property and the </span><span class="cls_007">IsChecked</span><span class="cls_004"> property of each button is now restored.</span></div>
<div style="position:absolute;left:5.00px;top:474.75px" class="cls_004"><span class="cls_004">Let's see the updated XAML.</span></div>
<div style="position:absolute;left:52.98px;top:498.00px" class="cls_007"><span class="cls_007"><UserControl</span></div>
<div style="position:absolute;left:52.98px;top:511.50px" class="cls_007"><span class="cls_007">x:Class="CompanyName.ApplicationName.Views.BitRateView"</span></div>
<div style="position:absolute;left:67.97px;top:525.00px" class="cls_007"><span class="cls_007">xmlns="</span><A HREF="http://schemas.microsoft.com/winfx/2006/xaml/presentation"/">http://schemas.microsoft.com/winfx/2006/xaml/presentation"</A> </div>
<div style="position:absolute;left:67.97px;top:538.50px" class="cls_007"><span class="cls_007">xmlns:x="</span><A HREF="http://schemas.microsoft.com/winfx/2006/xaml"/">http://schemas.microsoft.com/winfx/2006/xaml"</A> </div>
<div style="position:absolute;left:67.97px;top:552.00px" class="cls_007"><span class="cls_007">xmlns:mc="</span><A HREF="http://schemas.openxmlformats.org/markup-/">http://schemas.openxmlformats.org/markup-</A> </div>
<div style="position:absolute;left:52.98px;top:565.50px" class="cls_007"><span class="cls_007">compatibility/2006"</span></div>
<div style="position:absolute;left:67.97px;top:579.00px" class="cls_007"><span class="cls_007">xmlns:d="</span><A HREF="http://schemas.microsoft.com/expression/blend/2008"/">http://schemas.microsoft.com/expression/blend/2008"</A> </div>
<div style="position:absolute;left:67.97px;top:592.50px" class="cls_007"><span class="cls_007">xmlns:Converters="clr-</span></div>
<div style="position:absolute;left:52.98px;top:606.00px" class="cls_007"><span class="cls_007">namespace:CompanyName.ApplicationName.Converters;</span></div>
<div style="position:absolute;left:82.97px;top:619.50px" class="cls_007"><span class="cls_007">assembly=CompanyName.ApplicationName.Converters"</span></div>
<div style="position:absolute;left:67.97px;top:633.00px" class="cls_007"><span class="cls_007">xmlns:Enums="clr-</span></div>
<div style="position:absolute;left:52.98px;top:646.50px" class="cls_007"><span class="cls_007">namespace:CompanyName.ApplicationName.DataModels.</span></div>
<div style="position:absolute;left:82.97px;top:660.00px" class="cls_007"><span class="cls_007">Enums;assembly=CompanyName.ApplicationName.DataModels"</span></div>
<div style="position:absolute;left:67.97px;top:673.50px" class="cls_007"><span class="cls_007">mc:Ignorable="d" d:DesignHeight="90" d:DesignWidth="300"></span></div>
<div style="position:absolute;left:67.97px;top:687.00px" class="cls_007"><span class="cls_007"><UserControl.Resources></span></div>
<div style="position:absolute;left:82.97px;top:700.50px" class="cls_007"><span class="cls_007"><Converters:EnumToBoolConverter x:Key="EnumToBoolConverter" /></span></div>
<div style="position:absolute;left:67.97px;top:714.00px" class="cls_007"><span class="cls_007"></UserControl.Resources></span></div>
<div style="position:absolute;left:67.97px;top:727.50px" class="cls_007"><span class="cls_007"><GroupBox Header="Audio Quality" FontSize="14" Margin="20"</span></div>
<div style="position:absolute;left:82.97px;top:741.00px" class="cls_007"><span class="cls_007">HorizontalAlignment="Left" VerticalAlignment="Top" Padding="5"></span></div>
<div style="position:absolute;left:82.97px;top:754.50px" class="cls_007"><span class="cls_007"><ListBox ItemsSource="{Binding BitRates}"</span></div>
<div style="position:absolute;left:97.96px;top:768.00px" class="cls_007"><span class="cls_007">SelectedItem="{Binding BitRate}"></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:130726px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background165.jpg" width=612 height=792></div>
<div style="position:absolute;left:97.96px;top:3.00px" class="cls_007"><span class="cls_007"><ListBox.ItemTemplate></span></div>
<div style="position:absolute;left:112.96px;top:16.50px" class="cls_007"><span class="cls_007"><DataTemplate DataType="{x:Type Enums:BitRate}"></span></div>
<div style="position:absolute;left:127.95px;top:30.00px" class="cls_007"><span class="cls_007"><RadioButton Content="{Binding ., Converter=</span></div>
<div style="position:absolute;left:52.98px;top:43.50px" class="cls_007"><span class="cls_007">{StaticResource</span></div>
<div style="position:absolute;left:142.94px;top:57.00px" class="cls_007"><span class="cls_007">EnumToDescriptionStringConverter}}"</span></div>
<div style="position:absolute;left:142.94px;top:70.50px" class="cls_007"><span class="cls_007">IsChecked="{Binding IsSelected,</span></div>
<div style="position:absolute;left:142.94px;top:84.00px" class="cls_007"><span class="cls_007">RelativeSource={RelativeSource</span></div>
<div style="position:absolute;left:142.94px;top:97.50px" class="cls_007"><span class="cls_007">AncestorType={x:Type ListBoxItem}},</span></div>
<div style="position:absolute;left:52.98px;top:111.00px" class="cls_007"><span class="cls_007">FallbackValue=False}"</span></div>
<div style="position:absolute;left:142.94px;top:124.50px" class="cls_007"><span class="cls_007">VerticalContentAlignment="Center" /></span></div>
<div style="position:absolute;left:112.96px;top:138.00px" class="cls_007"><span class="cls_007"></DataTemplate></span></div>
<div style="position:absolute;left:97.96px;top:151.50px" class="cls_007"><span class="cls_007"></ListBox.ItemTemplate></span></div>
<div style="position:absolute;left:82.97px;top:165.00px" class="cls_007"><span class="cls_007"></ListBox></span></div>
<div style="position:absolute;left:67.97px;top:178.50px" class="cls_007"><span class="cls_007"></GroupBox></span></div>
<div style="position:absolute;left:52.98px;top:192.00px" class="cls_007"><span class="cls_007"></UserControl></span></div>
<div style="position:absolute;left:5.00px;top:225.00px" class="cls_004"><span class="cls_004">To update our earlier example, we need to add the new </span><span class="cls_007">Enums</span><span class="cls_004"> XML namespace prefix, so</span></div>
<div style="position:absolute;left:5.00px;top:243.00px" class="cls_004"><span class="cls_004">that we can specify our </span><span class="cls_007">BitRate</span><span class="cls_004"> enumeration type in the data template. Next, we need to</span></div>
<div style="position:absolute;left:5.00px;top:261.00px" class="cls_004"><span class="cls_004">update the content of our </span><span class="cls_007">GroupBox</span><span class="cls_004"> element. Now we're using a </span><span class="cls_007">ListBox</span><span class="cls_004"> control so that we</span></div>
<div style="position:absolute;left:5.00px;top:279.00px" class="cls_004"><span class="cls_004">can take advantage of its item selection capabilities.</span></div>
<div style="position:absolute;left:5.00px;top:297.00px" class="cls_004"><span class="cls_004">We data bind our </span><span class="cls_007">BitRates</span><span class="cls_004"> collection to the </span><span class="cls_007">ItemsSource</span><span class="cls_004"> property and our selected</span></div>
<div style="position:absolute;left:5.00px;top:315.00px" class="cls_007"><span class="cls_007">BitRate</span><span class="cls_004"> property to the </span><span class="cls_007">SelectedItem</span><span class="cls_004"> property of the </span><span class="cls_007">ListBox</span><span class="cls_004">. The one problem with this</span></div>
<div style="position:absolute;left:5.00px;top:333.00px" class="cls_004"><span class="cls_004">method is that as we're now using a </span><span class="cls_007">ListBox</span><span class="cls_004"> element in our example, we can see it and its</span></div>
<div style="position:absolute;left:5.00px;top:351.00px" class="cls_004"><span class="cls_004">contained </span><span class="cls_007">ListBoxItem</span><span class="cls_004"> objects. This is not how radio buttons are typically displayed.</span></div>
<div style="position:absolute;left:5.00px;top:481.50px" class="cls_004"><span class="cls_004">It's not a terrible problem and it can be easily fixed by declaring a few styles. We'll return to</span></div>
<div style="position:absolute;left:5.00px;top:499.50px" class="cls_004"><span class="cls_004">this example in the following chapter and demonstrate how we can style the listbox and its</span></div>
<div style="position:absolute;left:5.00px;top:517.50px" class="cls_004"><span class="cls_004">items to completely hide their use from the end users.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:131528px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background166.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_008"><span class="cls_008">Summary</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">We've covered a lot of important information in this chapter, from examining the binding path</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">syntax mini-language to exploring a number of different binding scenarios. We've</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">investigated the plethora of options that we're afforded when declaring our own</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">Dependency Properties and looked into the creation of Attached Properties, using some</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">interesting examples. Finally, we examined the finer details of data templating and explored</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">a number of ways of data binding to enumerations.</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">In the next chapter, we'll have an in-depth look at the various UI elements in the WPF</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">Framework and their most relevant properties. We'll investigate when to customize them</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">and when we need to create our own controls. We'll then explore the various ways of</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">modifying existing controls in WPF and finally, take a detailed look at how to create our own</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">custom controls.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:132330px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background167.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_002"><span class="cls_002">Chapter 5. Using the Right Controls for the</span></div>
<div style="position:absolute;left:5.00px;top:39.01px" class="cls_002"><span class="cls_002">Job</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">In this chapter, we'll first consider the existing controls that WPF offers us and look at how</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">we can use them to create the layouts that we require. We'll investigate the many ways that</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">we can modify these controls to avoid the need to create new controls.</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">We'll examine the various levels of functionality that are built into the existing controls and</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">then discover how to best declare our own controls when required. We'll take an in-depth</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">look at the various options that we have and determine when best to use each. Let's jump</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">straight in and take a look at the various layout controls.</span></div>
<div style="position:absolute;left:5.00px;top:201.01px" class="cls_008"><span class="cls_008">Investigating the built-in controls</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">There are a wide range of controls included in the .NET Framework. They cover most</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">common scenarios and it is rare that we will need to create our own controls in a typical</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">form-based application. All of the UI controls tend to have their functionality built up from a</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">large number of common base classes.</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">All controls will share the same core-level base classes that provide the core-level</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_004"><span class="cls_004">functionalities and then a number of derived framework-level classes that provide the</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_004"><span class="cls_004">functionality that is associated with the WPF Framework, such as data binding, styling and</span></div>
<div style="position:absolute;left:5.00px;top:363.75px" class="cls_004"><span class="cls_004">templating. Let's take a look at an example.</span></div>
<div style="position:absolute;left:5.00px;top:381.01px" class="cls_011"><span class="cls_011">Inheriting framework abilities</span></div>
<div style="position:absolute;left:5.00px;top:411.00px" class="cls_004"><span class="cls_004">As with the base classes in our application framework, the built-in WPF controls also have</span></div>
<div style="position:absolute;left:5.00px;top:429.00px" class="cls_004"><span class="cls_004">an inheritance hierarchy, with each successive base class offering some additional</span></div>
<div style="position:absolute;left:5.00px;top:447.00px" class="cls_004"><span class="cls_004">functionality. Let's look at the </span><span class="cls_007">Button</span><span class="cls_004"> class as an example. Here is the inheritance hierarchy</span></div>
<div style="position:absolute;left:5.00px;top:465.00px" class="cls_004"><span class="cls_004">of the </span><span class="cls_007">Button</span><span class="cls_004"> control:</span></div>
<div style="position:absolute;left:52.98px;top:488.25px" class="cls_007"><span class="cls_007">System.Object</span></div>
<div style="position:absolute;left:67.97px;top:501.75px" class="cls_007"><span class="cls_007">System.Windows.Threading.DispatcherObject</span></div>
<div style="position:absolute;left:82.97px;top:515.25px" class="cls_007"><span class="cls_007">System.Windows.DependencyObject</span></div>
<div style="position:absolute;left:97.96px;top:528.75px" class="cls_007"><span class="cls_007">System.Windows.Media.Visual</span></div>
<div style="position:absolute;left:112.96px;top:542.25px" class="cls_007"><span class="cls_007">System.Windows.UIElement</span></div>
<div style="position:absolute;left:127.95px;top:555.75px" class="cls_007"><span class="cls_007">System.Windows.FrameworkElement</span></div>
<div style="position:absolute;left:142.94px;top:569.25px" class="cls_007"><span class="cls_007">System.Windows.Controls.Control</span></div>
<div style="position:absolute;left:157.94px;top:582.75px" class="cls_007"><span class="cls_007">System.Windows.Controls.ContentControl</span></div>
<div style="position:absolute;left:172.93px;top:596.25px" class="cls_007"><span class="cls_007">System.Windows.Controls.Primitives.ButtonBase</span></div>
<div style="position:absolute;left:187.92px;top:609.75px" class="cls_007"><span class="cls_007">System.Windows.Controls.Button</span></div>
<div style="position:absolute;left:5.00px;top:630.00px" class="cls_004"><span class="cls_004">As with every object in the .NET Framework, we start with the </span><span class="cls_007">Object</span><span class="cls_004"> class, which provides</span></div>
<div style="position:absolute;left:5.00px;top:648.00px" class="cls_004"><span class="cls_004">low-level services to all classes. These include object comparison, finalization, and the</span></div>
<div style="position:absolute;left:5.00px;top:666.00px" class="cls_004"><span class="cls_004">ability to output a customizable string representation of each object.</span></div>
<div style="position:absolute;left:5.00px;top:684.00px" class="cls_004"><span class="cls_004">Next is the </span><span class="cls_007">DispatcherObject</span><span class="cls_004"> class, which provides each object with thread affinity and</span></div>
<div style="position:absolute;left:5.00px;top:702.00px" class="cls_004"><span class="cls_004">associates them with a </span><span class="cls_007">Dispatcher</span><span class="cls_004"> object. The </span><span class="cls_007">Dispatcher</span><span class="cls_004"> class manages a prioritized</span></div>
<div style="position:absolute;left:5.00px;top:720.00px" class="cls_004"><span class="cls_004">queue of work items for individual threads. Only the thread that the associated </span><span class="cls_007">Dispatcher</span></div>
<div style="position:absolute;left:5.00px;top:738.00px" class="cls_004"><span class="cls_004">object was created on can access each </span><span class="cls_007">DispatcherObject</span><span class="cls_004"> directly and this enables derived</span></div>
<div style="position:absolute;left:5.00px;top:756.00px" class="cls_004"><span class="cls_004">classes to enforce thread safety.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:133132px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background168.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">After the </span><span class="cls_007">DispatcherObject</span><span class="cls_004"> class, we have the </span><span class="cls_007">DependencyObject</span><span class="cls_004"> class, which enables all</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">derived classes to use the WPF property system and declare Dependency Properties. The</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_007"><span class="cls_007">GetValue</span><span class="cls_004"> and </span><span class="cls_007">SetValue</span><span class="cls_004"> methods that we call to access and set their values are also</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">provided by the </span><span class="cls_007">DependencyObject</span><span class="cls_004"> class.</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">Next up is the </span><span class="cls_007">Visual</span><span class="cls_004"> class, which has the primary role of providing rendering support. All</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">elements that are displayed in the UI will extend the </span><span class="cls_007">Visual</span><span class="cls_004"> class. In addition to rendering</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">each object, it also calculates their bounding box and provides support for hit testing,</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">clipping, and transformations.</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">Extending the </span><span class="cls_007">Visual</span><span class="cls_004"> class is the </span><span class="cls_007">UIElement</span><span class="cls_004"> class, which provides a number of core</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">services to all of its derived classes. These include the event and user input systems and</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">the ability to determine the element's layout appearance and rendering behavior.</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">Following on from that is the </span><span class="cls_007">FrameworkElement</span><span class="cls_004"> class, which provides the first framework-</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">level members, building upon the foundation of the core-level classes that it extends. It is</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">FrameworkElement</span><span class="cls_004"> class that enables data binding through the </span><span class="cls_007">DataContext</span><span class="cls_004"> property</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">and styling through the </span><span class="cls_007">Style</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">It also provides events that relate to an object's lifetime, an upgrade of the core-level layout</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">system to a full layout system and improved support for animations, among other things.</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">This is typically the lowest level class that we might want to extend if we were creating our</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_004"><span class="cls_004">own basic elements, as it enables derived classes to partake in the majority of the WPF UI</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_004"><span class="cls_004">capabilities.</span></div>
<div style="position:absolute;left:5.00px;top:363.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">Control</span><span class="cls_004"> class extends the </span><span class="cls_007">FrameworkElement</span><span class="cls_004"> class and is the base class for most of</span></div>
<div style="position:absolute;left:5.00px;top:381.75px" class="cls_004"><span class="cls_004">the WPF UI elements. It provides appearance templating through the use of its</span></div>
<div style="position:absolute;left:5.00px;top:399.75px" class="cls_007"><span class="cls_007">ControlTemplate</span><span class="cls_004"> functionality and a host of appearance-related properties. These include</span></div>
<div style="position:absolute;left:5.00px;top:417.75px" class="cls_004"><span class="cls_004">coloring properties, such as </span><span class="cls_007">Background</span><span class="cls_004">, </span><span class="cls_007">Foreground</span><span class="cls_004">, and </span><span class="cls_007">BorderBrush</span><span class="cls_004">, along with</span></div>
<div style="position:absolute;left:5.00px;top:435.75px" class="cls_004"><span class="cls_004">alignment and typeface properties.</span></div>
<div style="position:absolute;left:5.00px;top:453.75px" class="cls_004"><span class="cls_004">Extending the </span><span class="cls_007">Control</span><span class="cls_004"> class is the </span><span class="cls_007">ContentControl</span><span class="cls_004"> class, which enables controls to have</span></div>
<div style="position:absolute;left:5.00px;top:471.75px" class="cls_004"><span class="cls_004">one object of any CLR type as its content. This means that we can either set data objects</span></div>
<div style="position:absolute;left:5.00px;top:489.75px" class="cls_004"><span class="cls_004">or UI elements as the content, although we may need to provide a </span><span class="cls_007">DataTemplate</span><span class="cls_004"> for the</span></div>
<div style="position:absolute;left:5.00px;top:507.75px" class="cls_004"><span class="cls_004">data objects if they are of a custom type.</span></div>
<div style="position:absolute;left:5.00px;top:525.75px" class="cls_004"><span class="cls_004">The final class in the long line of parent classes that the </span><span class="cls_007">Button</span><span class="cls_004"> class extends is the</span></div>
<div style="position:absolute;left:5.00px;top:543.75px" class="cls_007"><span class="cls_007">ButtonBase</span><span class="cls_004"> class. In fact, this is the base class for all buttons in WPF and it adds useful</span></div>
<div style="position:absolute;left:5.00px;top:561.75px" class="cls_004"><span class="cls_004">functionality for buttons. This includes automatically converting certain keyboard events to</span></div>
<div style="position:absolute;left:5.00px;top:579.75px" class="cls_004"><span class="cls_004">mouse events, so that users can interact with the buttons without using a mouse.</span></div>
<div style="position:absolute;left:5.00px;top:597.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">Button</span><span class="cls_004"> class itself adds little to its inherited members, with only three related </span><span class="cls_007">bool</span></div>
<div style="position:absolute;left:5.00px;top:615.75px" class="cls_004"><span class="cls_004">properties; two that specify whether a button is the default button and one that specifies</span></div>
<div style="position:absolute;left:5.00px;top:633.75px" class="cls_004"><span class="cls_004">whether the button is a cancel button. We'll see an example of this shortly. It has an</span></div>
<div style="position:absolute;left:5.00px;top:651.75px" class="cls_004"><span class="cls_004">additional two protected overridden methods that get called, when the button is clicked, or</span></div>
<div style="position:absolute;left:5.00px;top:669.75px" class="cls_004"><span class="cls_004">when an automation peer is created for it.</span></div>
<div style="position:absolute;left:5.00px;top:687.75px" class="cls_004"><span class="cls_004">While WPF enables us to modify existing controls to such a degree that we rarely need to</span></div>
<div style="position:absolute;left:5.00px;top:705.75px" class="cls_004"><span class="cls_004">create our own, it is important to be aware of this inheritance hierarchy, so that we can</span></div>
<div style="position:absolute;left:5.00px;top:723.75px" class="cls_004"><span class="cls_004">extend the appropriate and most lightweight base class that fulfils our requirements, when</span></div>
<div style="position:absolute;left:5.00px;top:741.75px" class="cls_004"><span class="cls_004">we need to.</span></div>
<div style="position:absolute;left:5.00px;top:759.75px" class="cls_004"><span class="cls_004">For example, if we wanted to create our own custom button, it would typically make more</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:133934px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background169.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">sense to extend the </span><span class="cls_007">ButtonBase</span><span class="cls_004"> class, rather than the </span><span class="cls_007">Button</span><span class="cls_004"> class, and if we wanted to</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">create a totally unique control, we could extend the </span><span class="cls_007">FrameworkElement</span><span class="cls_004"> class. Now that we</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">have a good understanding of the make-up of the available controls, let's see how they are</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">displayed by the WPF layout system.</span></div>
<div style="position:absolute;left:5.00px;top:75.01px" class="cls_011"><span class="cls_011">Laying it on the line</span></div>
<div style="position:absolute;left:5.00px;top:105.00px" class="cls_004"><span class="cls_004">In WPF, the layout system is responsible for attaining the sizes of each element to be</span></div>
<div style="position:absolute;left:5.00px;top:123.00px" class="cls_004"><span class="cls_004">displayed, positioning them on the screen and then drawing them. As controls can be</span></div>
<div style="position:absolute;left:5.00px;top:141.00px" class="cls_004"><span class="cls_004">contained within other controls, the layout system works recursively, with each child</span></div>
<div style="position:absolute;left:5.00px;top:159.00px" class="cls_004"><span class="cls_004">control's overall position being determined by the position of its parent panel control.</span></div>
<div style="position:absolute;left:5.00px;top:177.00px" class="cls_004"><span class="cls_004">The layout system first measures each child in each panel in what is known as a measure</span></div>
<div style="position:absolute;left:5.00px;top:195.00px" class="cls_004"><span class="cls_004">pass. During this pass, each panel calls the </span><span class="cls_007">Measure</span><span class="cls_004"> method of each child element and they</span></div>
<div style="position:absolute;left:5.00px;top:213.00px" class="cls_004"><span class="cls_004">specify how much space they would ideally like to have; this determines the</span></div>
<div style="position:absolute;left:5.00px;top:231.00px" class="cls_007"><span class="cls_007">UIElement.DesiredSize</span><span class="cls_004"> property value. Note that this is not necessarily how much space</span></div>
<div style="position:absolute;left:5.00px;top:249.00px" class="cls_004"><span class="cls_004">they will be given.</span></div>
<div style="position:absolute;left:5.00px;top:267.00px" class="cls_004"><span class="cls_004">After the measure pass comes the arrange pass, when each panel calls the </span><span class="cls_007">Arrange</span></div>
<div style="position:absolute;left:5.00px;top:285.00px" class="cls_004"><span class="cls_004">method of each child element. During this pass, the panels generate the bounding boxes of</span></div>
<div style="position:absolute;left:5.00px;top:303.00px" class="cls_004"><span class="cls_004">each of their child elements, dependent upon their </span><span class="cls_007">DesiredSize</span><span class="cls_004"> values. The layout system</span></div>
<div style="position:absolute;left:5.00px;top:321.00px" class="cls_004"><span class="cls_004">will adjust these sizes to add any required margins or additional adjustments that may be</span></div>
<div style="position:absolute;left:5.00px;top:339.00px" class="cls_004"><span class="cls_004">needed.</span></div>
<div style="position:absolute;left:5.00px;top:357.00px" class="cls_004"><span class="cls_004">It returns a value to the input parameter of the panels' </span><span class="cls_007">ArrangeOverride</span><span class="cls_004"> method and each</span></div>
<div style="position:absolute;left:5.00px;top:375.00px" class="cls_004"><span class="cls_004">panel performs its own specific layout behavior before returning the possibly adjusted value.</span></div>
<div style="position:absolute;left:5.00px;top:393.00px" class="cls_004"><span class="cls_004">The layout system performs any remaining required adjustments before returning execution</span></div>
<div style="position:absolute;left:5.00px;top:411.00px" class="cls_004"><span class="cls_004">to the panel and completing the layout process.</span></div>
<div style="position:absolute;left:5.00px;top:429.00px" class="cls_004"><span class="cls_004">We need to be careful when developing our applications, to ensure that we do not</span></div>
<div style="position:absolute;left:5.00px;top:447.00px" class="cls_004"><span class="cls_004">unnecessarily trigger additional passes of the layout system, as this can lead to poor</span></div>
<div style="position:absolute;left:5.00px;top:465.00px" class="cls_004"><span class="cls_004">performance. This can occur when adding or removing items in a collection, applying</span></div>
<div style="position:absolute;left:5.00px;top:483.00px" class="cls_004"><span class="cls_004">transforms on the elements, or by calling the </span><span class="cls_007">UIElement.UpdateLayout</span><span class="cls_004"> method, which</span></div>
<div style="position:absolute;left:5.00px;top:501.00px" class="cls_004"><span class="cls_004">forces a new layout pass.</span></div>
<div style="position:absolute;left:5.00px;top:518.26px" class="cls_011"><span class="cls_011">Containing controls</span></div>
<div style="position:absolute;left:5.00px;top:548.25px" class="cls_004"><span class="cls_004">The existing controls can mostly be split into two main categories; those that provide layout</span></div>
<div style="position:absolute;left:5.00px;top:566.25px" class="cls_004"><span class="cls_004">support for other controls and those that make up the visible UI, and are arranged in it by</span></div>
<div style="position:absolute;left:5.00px;top:584.25px" class="cls_004"><span class="cls_004">the first category of controls. The first category of controls are of course panels and they</span></div>
<div style="position:absolute;left:5.00px;top:602.25px" class="cls_004"><span class="cls_004">provide a variety of ways to arrange their child controls in the UI.</span></div>
<div style="position:absolute;left:5.00px;top:620.25px" class="cls_004"><span class="cls_004">Some provide resizing capabilities, while others don't, and some are more efficient than</span></div>
<div style="position:absolute;left:5.00px;top:638.25px" class="cls_004"><span class="cls_004">others, so it's important to use the right panel for the job at hand. Additionally, different</span></div>
<div style="position:absolute;left:5.00px;top:656.25px" class="cls_004"><span class="cls_004">panels offer different layout behavior, so it is good to know what the available panels are</span></div>
<div style="position:absolute;left:5.00px;top:674.25px" class="cls_004"><span class="cls_004">and what they each offer us in terms of layout.</span></div>
<div style="position:absolute;left:5.00px;top:692.25px" class="cls_004"><span class="cls_004">All panels extend the abstract </span><span class="cls_007">Panel</span><span class="cls_004"> class and that extends the </span><span class="cls_007">FrameworkElement</span><span class="cls_004"> class, so</span></div>
<div style="position:absolute;left:5.00px;top:710.25px" class="cls_004"><span class="cls_004">it has all of the members and functionality of that class. However, it doesn't extend the</span></div>
<div style="position:absolute;left:5.00px;top:728.25px" class="cls_007"><span class="cls_007">Control</span><span class="cls_004"> class and so it cannot inherit its properties. It therefore adds its own </span><span class="cls_007">Background</span></div>
<div style="position:absolute;left:5.00px;top:746.25px" class="cls_004"><span class="cls_004">property to enable users to color the gaps between the panel's various items.</span></div>
<div style="position:absolute;left:5.00px;top:764.25px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">Panel</span><span class="cls_004"> class also provides a </span><span class="cls_007">Children</span><span class="cls_004"> property that represents the items in each panel,</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:134736px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background170.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">although we do not typically interact with this property unless creating a custom panel.</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">Instead, we can populate this collection by simply declaring our child elements directly</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">within the panel element in XAML.</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">We are able to do this because the </span><span class="cls_007">Panel</span><span class="cls_004"> class specifies the </span><span class="cls_007">Children</span><span class="cls_004"> property in a</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_007"><span class="cls_007">ContentPropertyAttribute</span><span class="cls_004"> attribute in its class definition. While the </span><span class="cls_007">Content</span><span class="cls_004"> property of a</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_007"><span class="cls_007">ContentControl</span><span class="cls_004"> normally enables us to add a single item of content, we are able to add</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">multiple items into panels because their </span><span class="cls_007">Children</span><span class="cls_004"> property, which is set as the content, is a</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">collection.</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">Another </span><span class="cls_007">Panel</span><span class="cls_004"> class property that we might need to use is the </span><span class="cls_007">IsItemsHost</span><span class="cls_004"> property, which</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">specifies whether a panel is to be used as a container for the items of an </span><span class="cls_007">ItemsControl</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">element, or not. The default value is </span><span class="cls_007">false</span><span class="cls_004">, and it makes no sense to use this property set</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">to </span><span class="cls_007">false</span><span class="cls_004">. In fact, it is only ever required in a very particular situation.</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">That situation is when we are replacing the default panel of an </span><span class="cls_007">ItemsControl</span><span class="cls_004">, or one of its</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">derived classes, such as a </span><span class="cls_007">ListBox</span><span class="cls_004">, in a </span><span class="cls_007">ControlTemplate</span><span class="cls_004">. By setting this property to </span><span class="cls_007">true</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">on a panel element in a </span><span class="cls_007">ControlTemplate</span><span class="cls_004">, we are telling WPF to place the generated</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">collection elements in the panel. Let's see a quick example of this:</span></div>
<div style="position:absolute;left:52.98px;top:297.00px" class="cls_007"><span class="cls_007"><ItemsControl ItemsSource="{Binding Users}"></span></div>
<div style="position:absolute;left:67.97px;top:310.50px" class="cls_007"><span class="cls_007"><ItemsControl.Template></span></div>
<div style="position:absolute;left:82.97px;top:324.00px" class="cls_007"><span class="cls_007"><ControlTemplate TargetType="{x:Type ItemsControl}"></span></div>
<div style="position:absolute;left:97.96px;top:337.50px" class="cls_007"><span class="cls_007"><StackPanel Orientation="Horizontal" IsItemsHost="True" /></span></div>
<div style="position:absolute;left:82.97px;top:351.00px" class="cls_007"><span class="cls_007"></ControlTemplate></span></div>
<div style="position:absolute;left:67.97px;top:364.50px" class="cls_007"><span class="cls_007"></ItemsControl.Template></span></div>
<div style="position:absolute;left:52.98px;top:378.00px" class="cls_007"><span class="cls_007"></ItemsControl></span></div>
<div style="position:absolute;left:5.00px;top:398.25px" class="cls_004"><span class="cls_004">In this simple example, we are replacing the default internal items panel of the</span></div>
<div style="position:absolute;left:5.00px;top:416.25px" class="cls_007"><span class="cls_007">ItemsControl</span><span class="cls_004"> element with a horizontal </span><span class="cls_007">StackPanel</span><span class="cls_004">. Note that this is a permanent</span></div>
<div style="position:absolute;left:5.00px;top:434.25px" class="cls_004"><span class="cls_004">replacement and no one can make further changes to this without providing a new</span></div>
<div style="position:absolute;left:5.00px;top:452.25px" class="cls_007"><span class="cls_007">ControlTemplate</span><span class="cls_004">. There is however, a far easier way to achieve the same result and we</span></div>
<div style="position:absolute;left:5.00px;top:470.25px" class="cls_004"><span class="cls_004">saw an example of this in the previous chapter.</span></div>
<div style="position:absolute;left:52.98px;top:493.50px" class="cls_007"><span class="cls_007"><ItemsControl ItemsSource="{Binding Users}"></span></div>
<div style="position:absolute;left:67.97px;top:507.00px" class="cls_007"><span class="cls_007"><ItemsControl.ItemsPanel></span></div>
<div style="position:absolute;left:82.97px;top:520.50px" class="cls_007"><span class="cls_007"><ItemsPanelTemplate></span></div>
<div style="position:absolute;left:97.96px;top:534.00px" class="cls_007"><span class="cls_007"><StackPanel Orientation="Horizontal" /></span></div>
<div style="position:absolute;left:82.97px;top:547.50px" class="cls_007"><span class="cls_007"></ItemsPanelTemplate></span></div>
<div style="position:absolute;left:67.97px;top:561.00px" class="cls_007"><span class="cls_007"></ItemsControl.ItemsPanel></span></div>
<div style="position:absolute;left:52.98px;top:574.50px" class="cls_007"><span class="cls_007"></ItemsControl></span></div>
<div style="position:absolute;left:5.00px;top:594.75px" class="cls_004"><span class="cls_004">In this alternative example, we simply provide a new </span><span class="cls_007">ItemsPanelTemplate</span><span class="cls_004"> for the</span></div>
<div style="position:absolute;left:5.00px;top:612.75px" class="cls_007"><span class="cls_007">ItemsControl</span><span class="cls_004"> through its </span><span class="cls_007">ItemsPanel</span><span class="cls_004"> property. Using this code, the internal panel can still</span></div>
<div style="position:absolute;left:5.00px;top:630.75px" class="cls_004"><span class="cls_004">be easily changed without the need to provide a new </span><span class="cls_007">ControlTemplate</span><span class="cls_004"> and so when we</span></div>
<div style="position:absolute;left:5.00px;top:648.75px" class="cls_004"><span class="cls_004">don't want other users to be able to swap out the inner panel, we use the first method,</span></div>
<div style="position:absolute;left:5.00px;top:666.75px" class="cls_004"><span class="cls_004">otherwise we use this method.</span></div>
<div style="position:absolute;left:5.00px;top:684.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">Panel</span><span class="cls_004"> class also declares a </span><span class="cls_007">ZIndex</span><span class="cls_004"> Attached Property, which can be used by child</span></div>
<div style="position:absolute;left:5.00px;top:702.75px" class="cls_004"><span class="cls_004">elements to specify a layered order within the panel. Child elements with higher values will</span></div>
<div style="position:absolute;left:5.00px;top:720.75px" class="cls_004"><span class="cls_004">appear above, or in front of, elements setting lower values, although this property is ignored</span></div>
<div style="position:absolute;left:5.00px;top:738.75px" class="cls_004"><span class="cls_004">in panels that do not overlap their children. We'll see an example of this in the next section,</span></div>
<div style="position:absolute;left:5.00px;top:756.75px" class="cls_004"><span class="cls_004">so let's now focus on the panels that derive from the </span><span class="cls_007">Panel</span><span class="cls_004"> class and what they offer us.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:135538px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background171.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.00px" class="cls_013"><span class="cls_013">Canvas</span></div>
<div style="position:absolute;left:5.00px;top:28.50px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">Canvas</span><span class="cls_004"> class enables us to explicitly position child elements using combinations of the</span></div>
<div style="position:absolute;left:5.00px;top:46.50px" class="cls_007"><span class="cls_007">Canvas.Top</span><span class="cls_004">, </span><span class="cls_007">Canvas.Left</span><span class="cls_004">, </span><span class="cls_007">Canvas.Bottom</span><span class="cls_004">, and </span><span class="cls_007">Canvas.Right</span><span class="cls_004"> Attached Properties. This is</span></div>
<div style="position:absolute;left:5.00px;top:64.50px" class="cls_004"><span class="cls_004">vaguely similar to the old Windows Forms system of control placement.</span></div>
<div style="position:absolute;left:5.00px;top:82.50px" class="cls_004"><span class="cls_004">However, when using WPF, we don't typically layout UI controls in a </span><span class="cls_007">Canvas</span><span class="cls_004">. Instead, we</span></div>
<div style="position:absolute;left:5.00px;top:100.50px" class="cls_004"><span class="cls_004">tend to use them more for displaying shapes, constructing graphs, showing animations, or</span></div>
<div style="position:absolute;left:5.00px;top:118.50px" class="cls_004"><span class="cls_004">drawing applications. Take the following example:</span></div>
<div style="position:absolute;left:52.98px;top:141.75px" class="cls_007"><span class="cls_007"><Canvas Width="256" Height="109" Background="Black"></span></div>
<div style="position:absolute;left:67.97px;top:155.25px" class="cls_007"><span class="cls_007"><Canvas.Resources></span></div>
<div style="position:absolute;left:82.97px;top:168.75px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type Ellipse}"></span></div>
<div style="position:absolute;left:97.96px;top:182.25px" class="cls_007"><span class="cls_007"><Setter Property="Width" Value="50" /></span></div>
<div style="position:absolute;left:97.96px;top:195.75px" class="cls_007"><span class="cls_007"><Setter Property="Height" Value="50" /></span></div>
<div style="position:absolute;left:97.96px;top:209.25px" class="cls_007"><span class="cls_007"><Setter Property="Stroke" Value="Black" /></span></div>
<div style="position:absolute;left:97.96px;top:222.75px" class="cls_007"><span class="cls_007"><Setter Property="StrokeThickness" Value="3" /></span></div>
<div style="position:absolute;left:82.97px;top:236.25px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:67.97px;top:249.75px" class="cls_007"><span class="cls_007"></Canvas.Resources></span></div>
<div style="position:absolute;left:67.97px;top:263.25px" class="cls_007"><span class="cls_007"><Canvas Canvas.Left="3" Canvas.Top="3" Background="Orange"</span></div>
<div style="position:absolute;left:82.97px;top:276.75px" class="cls_007"><span class="cls_007">Width="123.5" Height="50"></span></div>
<div style="position:absolute;left:82.97px;top:290.25px" class="cls_007"><span class="cls_007"><Ellipse Canvas.Top="25" Canvas.Left="25" Fill="Cyan" /></span></div>
<div style="position:absolute;left:67.97px;top:303.75px" class="cls_007"><span class="cls_007"></Canvas></span></div>
<div style="position:absolute;left:67.97px;top:317.25px" class="cls_007"><span class="cls_007"><Canvas Canvas.Left="129.5" Canvas.Top="3" Background="Orange"</span></div>
<div style="position:absolute;left:82.97px;top:330.75px" class="cls_007"><span class="cls_007">Width="123.5" Height="50" Panel.ZIndex="1" /></span></div>
<div style="position:absolute;left:67.97px;top:344.25px" class="cls_007"><span class="cls_007"><Canvas Canvas.Left="3" Canvas.Top="56" Background="Red"</span></div>
<div style="position:absolute;left:52.98px;top:357.75px" class="cls_007"><span class="cls_007">Width="250"</span></div>
<div style="position:absolute;left:82.97px;top:371.25px" class="cls_007"><span class="cls_007">Height="50" ClipToBounds="True"></span></div>
<div style="position:absolute;left:82.97px;top:384.75px" class="cls_007"><span class="cls_007"><Ellipse Canvas.Top="-25" Canvas.Left="175" Fill="Lime" /></span></div>
<div style="position:absolute;left:67.97px;top:398.25px" class="cls_007"><span class="cls_007"></Canvas></span></div>
<div style="position:absolute;left:67.97px;top:411.75px" class="cls_007"><span class="cls_007"><Ellipse Canvas.Top="29.5" Canvas.Left="103" Fill="Yellow" /></span></div>
<div style="position:absolute;left:52.98px;top:425.25px" class="cls_007"><span class="cls_007"></Canvas></span></div>
<div style="position:absolute;left:5.00px;top:445.50px" class="cls_004"><span class="cls_004">This example demonstrates a number of important points, so let's first see the visual output</span></div>
<div style="position:absolute;left:5.00px;top:463.50px" class="cls_004"><span class="cls_004">of this code before discussing it:</span></div>
<div style="position:absolute;left:5.00px;top:633.75px" class="cls_004"><span class="cls_004">The top-left rectangle is the output from one canvas, the top-right and bottom ones are</span></div>
<div style="position:absolute;left:5.00px;top:651.75px" class="cls_004"><span class="cls_004">from two others and they are all contained within a parent canvas element with a black</span></div>
<div style="position:absolute;left:5.00px;top:669.75px" class="cls_004"><span class="cls_004">background. The three inner canvases are spaced to give the effect that they each have a</span></div>
<div style="position:absolute;left:5.00px;top:687.75px" class="cls_004"><span class="cls_004">border. They have been declared in the order top-left, top-right, bottom, and the last</span></div>
<div style="position:absolute;left:5.00px;top:705.75px" class="cls_004"><span class="cls_004">element to be declared is the middle circle.</span></div>
<div style="position:absolute;left:5.00px;top:723.75px" class="cls_004"><span class="cls_004">The left circle is being drawn in the top-left canvas and we can see where it is overlapping</span></div>
<div style="position:absolute;left:5.00px;top:741.75px" class="cls_004"><span class="cls_004">the canvas' apparent bottom border, which shows that it is not being clipped by its parent</span></div>
<div style="position:absolute;left:5.00px;top:759.75px" class="cls_004"><span class="cls_004">canvas. However, it is being clipped by the lower canvas element and this demonstrates</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:136340px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background172.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">that UI elements that are declared later will be displayed over the top of earlier declared</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">elements.</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">Nevertheless, the second canvas to be declared is clipping the middle circle, which was the</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">last declared element. This demonstrates that setting the </span><span class="cls_007">Panel.ZIndex</span><span class="cls_004"> property on an</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">element to any positive number will position that element above all others that have not</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">explicitly set this property. The default value for this property is zero, so an element that has</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">this property set to </span><span class="cls_007">1</span><span class="cls_004"> will be rendered on top of all elements that have not explicitly set a</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">value for it.</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">The next element to be declared is the bottom rectangle and the right circle is declared</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">within it. Now, as this element is declared after the top canvases, you might expect that the</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">right circle would overlap the upper-right canvas. While this would normally be the case, this</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">won't happen with our example for two reasons.</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">The first, as we've just found out, is because the upper-right panel has a higher </span><span class="cls_007">ZIndex</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">property value than the lower panel and the second reason is because we have set the</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_007"><span class="cls_007">UIElement.ClipToBounds</span><span class="cls_004"> property to </span><span class="cls_007">true</span><span class="cls_004">, which is used by the </span><span class="cls_007">Canvas</span><span class="cls_004"> panel to determine</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">whether it should clip the visual content of any children that may lie outside the bounds of</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">the panel.</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">This is commonly used with animations, to enable a visual to be hidden out of the panel</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_004"><span class="cls_004">bounds and then slid into view in reaction to some event. We can tell that the right circle has</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_004"><span class="cls_004">been clipped by its parent panel because we can see its apparent top border, which is</span></div>
<div style="position:absolute;left:5.00px;top:363.75px" class="cls_004"><span class="cls_004">outside its bounds.</span></div>
<div style="position:absolute;left:5.00px;top:381.75px" class="cls_004"><span class="cls_004">The last element to be declared is the middle circle and we can see that apart from the</span></div>
<div style="position:absolute;left:5.00px;top:399.75px" class="cls_004"><span class="cls_004">overlapping canvas element with the higher </span><span class="cls_007">ZIndex</span><span class="cls_004"> property value, it overlaps all of the</span></div>
<div style="position:absolute;left:5.00px;top:417.75px" class="cls_004"><span class="cls_004">other elements. Note that the </span><span class="cls_007">Canvas</span><span class="cls_004"> panel does not perform any kind of resizing on its</span></div>
<div style="position:absolute;left:5.00px;top:435.75px" class="cls_004"><span class="cls_004">children, so it is not typically used for generating form type UI.</span></div>
<div style="position:absolute;left:5.00px;top:453.00px" class="cls_013"><span class="cls_013">DockPanel</span></div>
<div style="position:absolute;left:5.00px;top:478.50px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">DockPanel</span><span class="cls_004"> class is primarily used in the top levels of the control hierarchy to lay out the</span></div>
<div style="position:absolute;left:5.00px;top:496.50px" class="cls_004"><span class="cls_004">top-level controls. It provides us with the ability to dock controls to various parts of the</span></div>
<div style="position:absolute;left:5.00px;top:514.50px" class="cls_004"><span class="cls_004">screen, for example, a menu to the top, a context menu to the left, a status bar to the</span></div>
<div style="position:absolute;left:5.00px;top:532.50px" class="cls_004"><span class="cls_004">bottom and our main View content control to the remainder of the screen.</span></div>
<div style="position:absolute;left:5.00px;top:752.25px" class="cls_004"><span class="cls_004">This layout shown in the preceding image can be easily achieved with just the following</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:137142px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background173.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">XAML:</span></div>
<div style="position:absolute;left:52.98px;top:27.00px" class="cls_007"><span class="cls_007"><DockPanel></span></div>
<div style="position:absolute;left:67.97px;top:40.50px" class="cls_007"><span class="cls_007"><DockPanel.Resources></span></div>
<div style="position:absolute;left:82.97px;top:54.00px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type TextBlock}"></span></div>
<div style="position:absolute;left:97.96px;top:67.50px" class="cls_007"><span class="cls_007"><Setter Property="HorizontalAlignment" Value="Center" /></span></div>
<div style="position:absolute;left:97.96px;top:81.00px" class="cls_007"><span class="cls_007"><Setter Property="VerticalAlignment" Value="Center" /></span></div>
<div style="position:absolute;left:97.96px;top:94.50px" class="cls_007"><span class="cls_007"><Setter Property="FontSize" Value="14" /></span></div>
<div style="position:absolute;left:82.97px;top:108.00px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:82.97px;top:121.50px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type Border}"></span></div>
<div style="position:absolute;left:97.96px;top:135.00px" class="cls_007"><span class="cls_007"><Setter Property="BorderBrush" Value="Black" /></span></div>
<div style="position:absolute;left:97.96px;top:148.50px" class="cls_007"><span class="cls_007"><Setter Property="BorderThickness" Value="1" /></span></div>
<div style="position:absolute;left:82.97px;top:162.00px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:67.97px;top:175.50px" class="cls_007"><span class="cls_007"></DockPanel.Resources></span></div>
<div style="position:absolute;left:67.97px;top:189.00px" class="cls_007"><span class="cls_007"><Border Padding="0,3" DockPanel.Dock="Top"></span></div>
<div style="position:absolute;left:82.97px;top:202.50px" class="cls_007"><span class="cls_007"><TextBlock Text="Menu Bar" /></span></div>
<div style="position:absolute;left:67.97px;top:216.00px" class="cls_007"><span class="cls_007"></Border></span></div>
<div style="position:absolute;left:67.97px;top:229.50px" class="cls_007"><span class="cls_007"><Border Padding="0,3" DockPanel.Dock="Bottom"></span></div>
<div style="position:absolute;left:82.97px;top:243.00px" class="cls_007"><span class="cls_007"><TextBlock Text="Status Bar" /></span></div>
<div style="position:absolute;left:67.97px;top:256.50px" class="cls_007"><span class="cls_007"></Border></span></div>
<div style="position:absolute;left:67.97px;top:270.00px" class="cls_007"><span class="cls_007"><Border Width="100" DockPanel.Dock="Left"></span></div>
<div style="position:absolute;left:82.97px;top:283.50px" class="cls_007"><span class="cls_007"><TextBlock Text="Context Menu" TextWrapping="Wrap" /></span></div>
<div style="position:absolute;left:67.97px;top:297.00px" class="cls_007"><span class="cls_007"></Border></span></div>
<div style="position:absolute;left:67.97px;top:310.50px" class="cls_007"><span class="cls_007"><Border></span></div>
<div style="position:absolute;left:82.97px;top:324.00px" class="cls_007"><span class="cls_007"><TextBlock Text="View" /></span></div>
<div style="position:absolute;left:67.97px;top:337.50px" class="cls_007"><span class="cls_007"></Border></span></div>
<div style="position:absolute;left:52.98px;top:351.00px" class="cls_007"><span class="cls_007"></DockPanel></span></div>
<div style="position:absolute;left:5.00px;top:371.25px" class="cls_004"><span class="cls_004">We specify where we want each element within the panel to be docked using the</span></div>
<div style="position:absolute;left:5.00px;top:389.25px" class="cls_007"><span class="cls_007">DockPanel.Dock</span><span class="cls_004"> Attached Property. We can specify the left, right, top, and bottom of the</span></div>
<div style="position:absolute;left:5.00px;top:407.25px" class="cls_004"><span class="cls_004">panel. The remaining space is normally filled by the last child that does not explicitly set one</span></div>
<div style="position:absolute;left:5.00px;top:425.25px" class="cls_004"><span class="cls_004">of the </span><span class="cls_007">Dock</span><span class="cls_004"> property. However, if that is not the behavior that we want, then we can set the</span></div>
<div style="position:absolute;left:5.00px;top:443.25px" class="cls_007"><span class="cls_007">LastChildFill</span><span class="cls_004"> property to </span><span class="cls_007">false</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:461.25px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">DockPanel</span><span class="cls_004"> will automatically resize itself to fit its content, unless its dimensions are</span></div>
<div style="position:absolute;left:5.00px;top:479.25px" class="cls_004"><span class="cls_004">specified, either explicitly using the </span><span class="cls_007">Width</span><span class="cls_004"> and </span><span class="cls_007">Height</span><span class="cls_004"> properties, or implicitly by a parent</span></div>
<div style="position:absolute;left:5.00px;top:497.25px" class="cls_004"><span class="cls_004">panel. If it and its children both have dimensions specified for them, there is a chance that</span></div>
<div style="position:absolute;left:5.00px;top:515.25px" class="cls_004"><span class="cls_004">certain children will not be provided with enough space and not be displayed correctly, as</span></div>
<div style="position:absolute;left:5.00px;top:533.25px" class="cls_004"><span class="cls_004">the last child is the only child that can be resized by the </span><span class="cls_007">DockPanel</span><span class="cls_004">. It should also be noted</span></div>
<div style="position:absolute;left:5.00px;top:551.25px" class="cls_004"><span class="cls_004">that this panel does not overlap its child elements.</span></div>
<div style="position:absolute;left:5.00px;top:569.25px" class="cls_004"><span class="cls_004">Also note that the order that the children are declared in will affect the space and position</span></div>
<div style="position:absolute;left:5.00px;top:587.25px" class="cls_004"><span class="cls_004">that they are each provided with. For example, if we wanted the menu bar to fill the top of</span></div>
<div style="position:absolute;left:5.00px;top:605.25px" class="cls_004"><span class="cls_004">the screen, the context menu to take the remaining left side and the View and the status bar</span></div>
<div style="position:absolute;left:5.00px;top:623.25px" class="cls_004"><span class="cls_004">to take the remaining space, we could just declare the context menu before the status bar.</span></div>
<div style="position:absolute;left:67.97px;top:660.00px" class="cls_007"><span class="cls_007"><Border Padding="0,3" DockPanel.Dock="Top"></span></div>
<div style="position:absolute;left:82.97px;top:673.50px" class="cls_007"><span class="cls_007"><TextBlock Text="Menu Bar" /></span></div>
<div style="position:absolute;left:67.97px;top:687.00px" class="cls_007"><span class="cls_007"></Border></span></div>
<div style="position:absolute;left:67.97px;top:700.50px" class="cls_007"><span class="cls_007"><Border Width="100" DockPanel.Dock="Left"></span></div>
<div style="position:absolute;left:82.97px;top:714.00px" class="cls_007"><span class="cls_007"><TextBlock Text="Context Menu" TextWrapping="Wrap" /></span></div>
<div style="position:absolute;left:67.97px;top:727.50px" class="cls_007"><span class="cls_007"></Border></span></div>
<div style="position:absolute;left:67.97px;top:741.00px" class="cls_007"><span class="cls_007"><Border Padding="0,3" DockPanel.Dock="Bottom"></span></div>
<div style="position:absolute;left:82.97px;top:754.50px" class="cls_007"><span class="cls_007"><TextBlock Text="Status Bar" /></span></div>
<div style="position:absolute;left:67.97px;top:768.00px" class="cls_007"><span class="cls_007"></Border></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:137944px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background174.jpg" width=612 height=792></div>
<div style="position:absolute;left:67.97px;top:3.00px" class="cls_007"><span class="cls_007"><Border></span></div>
<div style="position:absolute;left:82.97px;top:16.50px" class="cls_007"><span class="cls_007"><TextBlock Text="View" /></span></div>
<div style="position:absolute;left:67.97px;top:30.00px" class="cls_007"><span class="cls_007"></Border></span></div>
<div style="position:absolute;left:5.00px;top:63.75px" class="cls_004"><span class="cls_004">This slight change would result in the required layout.</span></div>
<div style="position:absolute;left:5.00px;top:282.75px" class="cls_013"><span class="cls_013">Grid</span></div>
<div style="position:absolute;left:5.00px;top:308.25px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">Grid</span><span class="cls_004"> panel is by far the most commonly used when it comes to laying out typical UI</span></div>
<div style="position:absolute;left:5.00px;top:326.25px" class="cls_004"><span class="cls_004">controls. It is the most versatile and enables us to perform a number of tricks to end up with</span></div>
<div style="position:absolute;left:5.00px;top:344.25px" class="cls_004"><span class="cls_004">the layout that we require. It offers a flexible row and column based layout system that we</span></div>
<div style="position:absolute;left:5.00px;top:362.25px" class="cls_004"><span class="cls_004">can use to build UIs with a fluid layout. Fluid layouts are able to react and change size when</span></div>
<div style="position:absolute;left:5.00px;top:380.25px" class="cls_004"><span class="cls_004">users resize their application windows.</span></div>
<div style="position:absolute;left:5.00px;top:398.25px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">Grid</span><span class="cls_004"> is one of the few panels that can resize all of its child elements, depending on the</span></div>
<div style="position:absolute;left:5.00px;top:416.25px" class="cls_004"><span class="cls_004">available size and so that makes it one of the most performance-intensive panels.</span></div>
<div style="position:absolute;left:5.00px;top:434.25px" class="cls_004"><span class="cls_004">Therefore, if we don't need the functionality that it provides, we should use a more</span></div>
<div style="position:absolute;left:5.00px;top:452.25px" class="cls_004"><span class="cls_004">performant panel, such as a </span><span class="cls_007">Canvas</span><span class="cls_004">, or </span><span class="cls_007">StackPanel</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:470.25px" class="cls_004"><span class="cls_004">The children of a </span><span class="cls_007">Grid</span><span class="cls_004"> panel can each set their </span><span class="cls_007">Margin</span><span class="cls_004"> property to be laid out using</span></div>
<div style="position:absolute;left:5.00px;top:488.25px" class="cls_004"><span class="cls_004">absolute coordinates, in a similar fashion to the </span><span class="cls_007">Canvas</span><span class="cls_004"> panel. However, this should be</span></div>
<div style="position:absolute;left:5.00px;top:506.25px" class="cls_004"><span class="cls_004">avoided wherever possible, because that will break the fluidity of our UI. Instead, we</span></div>
<div style="position:absolute;left:5.00px;top:524.25px" class="cls_004"><span class="cls_004">typically define our desired layout using the grid's </span><span class="cls_007">RowDefinitions</span><span class="cls_004"> and </span><span class="cls_007">ColumnDefinitions</span></div>
<div style="position:absolute;left:5.00px;top:542.25px" class="cls_004"><span class="cls_004">collections and the </span><span class="cls_007">Grid.Row</span><span class="cls_004"> and </span><span class="cls_007">Grid.Column</span><span class="cls_004"> Attached Properties.</span></div>
<div style="position:absolute;left:5.00px;top:560.25px" class="cls_004"><span class="cls_004">While we can again hard code exact widths and heights for our rows and columns, we</span></div>
<div style="position:absolute;left:5.00px;top:578.25px" class="cls_004"><span class="cls_004">usually try to avoid doing so for the same reason. Instead, we generally take advantage of</span></div>
<div style="position:absolute;left:5.00px;top:596.25px" class="cls_004"><span class="cls_004">the grid's sizing behavior and declare our rows and columns, predominantly using one of</span></div>
<div style="position:absolute;left:5.00px;top:614.25px" class="cls_004"><span class="cls_004">two values.</span></div>
<div style="position:absolute;left:5.00px;top:632.25px" class="cls_004"><span class="cls_004">The first is the </span><span class="cls_007">Auto</span><span class="cls_004"> value, which takes its size from its content and the second is the default</span></div>
<div style="position:absolute;left:5.00px;top:650.25px" class="cls_007"><span class="cls_007">*</span><span class="cls_004"> star-sized value, which takes all of the remaining space. Typically, we set all columns or</span></div>
<div style="position:absolute;left:5.00px;top:668.25px" class="cls_004"><span class="cls_004">rows to </span><span class="cls_007">Auto</span><span class="cls_004"> except the one(s) that contain(s) the most important data, which is/are set to</span></div>
<div style="position:absolute;left:5.00px;top:686.25px" class="cls_007"><span class="cls_007">*</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:704.25px" class="cls_004"><span class="cls_004">Note that if we have more than one star-sized column, then the space is normally divided</span></div>
<div style="position:absolute;left:5.00px;top:722.25px" class="cls_004"><span class="cls_004">equally between them. However, if we need unequal divisions of the remaining space, then</span></div>
<div style="position:absolute;left:5.00px;top:740.25px" class="cls_004"><span class="cls_004">we can specify a multiplier number with the asterisk, which will multiply the proportion of</span></div>
<div style="position:absolute;left:5.00px;top:758.25px" class="cls_004"><span class="cls_004">space that that row or column will be provided with. Let's see an example to help to clarify</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:138746px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background175.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">this:</span></div>
<div style="position:absolute;left:52.98px;top:27.00px" class="cls_007"><span class="cls_007"><Grid TextElement.FontSize="14" Margin="10"></span></div>
<div style="position:absolute;left:67.97px;top:40.50px" class="cls_007"><span class="cls_007"><Grid.ColumnDefinitions></span></div>
<div style="position:absolute;left:82.97px;top:54.00px" class="cls_007"><span class="cls_007"><ColumnDefinition Width="2.5*" /></span></div>
<div style="position:absolute;left:82.97px;top:67.50px" class="cls_007"><span class="cls_007"><ColumnDefinition /></span></div>
<div style="position:absolute;left:82.97px;top:81.00px" class="cls_007"><span class="cls_007"><ColumnDefinition /></span></div>
<div style="position:absolute;left:67.97px;top:94.50px" class="cls_007"><span class="cls_007"></Grid.ColumnDefinitions></span></div>
<div style="position:absolute;left:67.97px;top:108.00px" class="cls_007"><span class="cls_007"><Grid.RowDefinitions></span></div>
<div style="position:absolute;left:82.97px;top:121.50px" class="cls_007"><span class="cls_007"><RowDefinition /></span></div>
<div style="position:absolute;left:82.97px;top:135.00px" class="cls_007"><span class="cls_007"><RowDefinition Height="Auto" /></span></div>
<div style="position:absolute;left:67.97px;top:148.50px" class="cls_007"><span class="cls_007"></Grid.RowDefinitions></span></div>
<div style="position:absolute;left:67.97px;top:162.00px" class="cls_007"><span class="cls_007"><TextBlock Grid.ColumnSpan="3" HorizontalAlignment="Center"</span></div>
<div style="position:absolute;left:82.97px;top:175.50px" class="cls_007"><span class="cls_007">VerticalAlignment="Center" Text="Are you sure you want to</span></div>
<div style="position:absolute;left:52.98px;top:189.00px" class="cls_007"><span class="cls_007">continue?"</span></div>
<div style="position:absolute;left:82.97px;top:202.50px" class="cls_007"><span class="cls_007">Margin="40" /></span></div>
<div style="position:absolute;left:67.97px;top:216.00px" class="cls_007"><span class="cls_007"><Button Grid.Row="1" Grid.Column="1" Content="Cancel"</span></div>
<div style="position:absolute;left:52.98px;top:229.50px" class="cls_007"><span class="cls_007">IsCancel="True"</span></div>
<div style="position:absolute;left:82.97px;top:243.00px" class="cls_007"><span class="cls_007">Height="26" Margin="0,0,2.5,0" /></span></div>
<div style="position:absolute;left:67.97px;top:256.50px" class="cls_007"><span class="cls_007"><Button Grid.Row="1" Grid.Column="2" Content="Ok"</span></div>
<div style="position:absolute;left:52.98px;top:270.00px" class="cls_007"><span class="cls_007">IsDefault="True"</span></div>
<div style="position:absolute;left:82.97px;top:283.50px" class="cls_007"><span class="cls_007">Height="26" Margin="2.5,0,0,0" /></span></div>
<div style="position:absolute;left:52.98px;top:297.00px" class="cls_007"><span class="cls_007"></Grid></span></div>
<div style="position:absolute;left:5.00px;top:317.25px" class="cls_004"><span class="cls_004">This example demonstrates a number of points, so let's see the rendered output before</span></div>
<div style="position:absolute;left:5.00px;top:335.25px" class="cls_004"><span class="cls_004">continuing.</span></div>
<div style="position:absolute;left:5.00px;top:532.50px" class="cls_004"><span class="cls_004">Here, we have a very basic confirmation dialog control. It is formed with a </span><span class="cls_007">Grid</span><span class="cls_004"> panel with</span></div>
<div style="position:absolute;left:5.00px;top:550.50px" class="cls_004"><span class="cls_004">three columns and two rows. Note that as single star-sizing is used as the default width and</span></div>
<div style="position:absolute;left:5.00px;top:568.50px" class="cls_004"><span class="cls_004">height values for the </span><span class="cls_007">ColumnDefinition</span><span class="cls_004"> and </span><span class="cls_007">RowDefinition</span><span class="cls_004"> elements respectively, we do</span></div>
<div style="position:absolute;left:5.00px;top:586.50px" class="cls_004"><span class="cls_004">not need to explicitly set them and can simply declare empty elements.</span></div>
<div style="position:absolute;left:5.00px;top:604.50px" class="cls_004"><span class="cls_004">Therefore, in our example, the second and third columns and the first row will use star-</span></div>
<div style="position:absolute;left:5.00px;top:622.50px" class="cls_004"><span class="cls_004">sizing and take all of the remaining space. The first column also uses star-sizing, however it</span></div>
<div style="position:absolute;left:5.00px;top:640.50px" class="cls_004"><span class="cls_004">specifies a multiplier value of </span><span class="cls_007">2.5</span><span class="cls_004">. As such, it will be provided with two and a half times the</span></div>
<div style="position:absolute;left:5.00px;top:658.50px" class="cls_004"><span class="cls_004">amount of space that the other two columns will each have.</span></div>
<div style="position:absolute;left:5.00px;top:676.50px" class="cls_004"><span class="cls_004">Note that this first column is only used to push the buttons in the other two columns to the</span></div>
<div style="position:absolute;left:5.00px;top:694.50px" class="cls_004"><span class="cls_004">correct position. While the </span><span class="cls_007">TextBlock</span><span class="cls_004"> element is declared in the first column, it does not</span></div>
<div style="position:absolute;left:5.00px;top:712.50px" class="cls_004"><span class="cls_004">only reside in that column, because it has also specified the </span><span class="cls_007">Grid.ColumnSpan</span><span class="cls_004"> Attached</span></div>
<div style="position:absolute;left:5.00px;top:730.50px" class="cls_004"><span class="cls_004">Property, which allows it to spread out across multiple columns. The </span><span class="cls_007">Grid.RowSpan</span></div>
<div style="position:absolute;left:5.00px;top:748.50px" class="cls_004"><span class="cls_004">Attached Property does the same for rows.</span></div>
<div style="position:absolute;left:5.00px;top:766.50px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">Grid.Row</span><span class="cls_004"> and </span><span class="cls_007">Grid.Column</span><span class="cls_004"> Attached Properties are used by each element to specify</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:139548px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background176.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">which cell they should be rendered in. However, the default value for these properties is</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">zero and so, when we want to declare an element within the first column or row of the</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">panel, we can omit the setting of these properties, as has been done for the </span><span class="cls_007">TextBlock</span><span class="cls_004"> in</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">our example.</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_005">Cancel</span><span class="cls_004"> button has been declared in the second row and column and sets the </span><span class="cls_007">IsCancel</span></div>
<div style="position:absolute;left:5.00px;top:94.50px" class="cls_004"><span class="cls_004">property to </span><span class="cls_007">true</span><span class="cls_004">, which enables the users to select it by pressing the </span><span class="cls_012">Esc</span><span class="cls_006"> </span><span class="cls_004">key on their</span></div>
<div style="position:absolute;left:5.00px;top:113.25px" class="cls_004"><span class="cls_004">keyboards. The </span><span class="cls_005">Ok</span><span class="cls_004"> button sits next to it in the third column and sets the </span><span class="cls_007">IsDefault</span><span class="cls_004"> key to</span></div>
<div style="position:absolute;left:5.00px;top:132.00px" class="cls_007"><span class="cls_007">true</span><span class="cls_004">, which enables users to invoke it by pressing the </span><span class="cls_012">Enter</span><span class="cls_006"> </span><span class="cls_004">key on their keyboards.</span></div>
<div style="position:absolute;left:5.00px;top:150.75px" class="cls_004"><span class="cls_004">Note that we could have set the lower </span><span class="cls_007">RowDefinition.Height</span><span class="cls_004"> property to </span><span class="cls_007">26</span><span class="cls_004"> instead of</span></div>
<div style="position:absolute;left:5.00px;top:168.75px" class="cls_004"><span class="cls_004">setting that on each button explicitly and the end result would have been the same, as the</span></div>
<div style="position:absolute;left:5.00px;top:186.75px" class="cls_007"><span class="cls_007">Auto</span><span class="cls_004"> value would be calculated from their height anyway. Also, note that the </span><span class="cls_007">Margin</span></div>
<div style="position:absolute;left:5.00px;top:204.75px" class="cls_004"><span class="cls_004">property has been set on a few elements here for spacing purposes only, rather than for</span></div>
<div style="position:absolute;left:5.00px;top:222.75px" class="cls_004"><span class="cls_004">absolute positioning purposes.</span></div>
<div style="position:absolute;left:5.00px;top:240.75px" class="cls_004"><span class="cls_004">There are two other useful properties declared by the </span><span class="cls_007">Grid</span><span class="cls_004"> class. The first is the</span></div>
<div style="position:absolute;left:5.00px;top:258.75px" class="cls_007"><span class="cls_007">ShowGridLines</span><span class="cls_004"> property, which as you can imagine, shows the borders of the rows and</span></div>
<div style="position:absolute;left:5.00px;top:276.75px" class="cls_004"><span class="cls_004">columns in the panel when set to </span><span class="cls_007">true</span><span class="cls_004">. While not really required for simple layouts as in the</span></div>
<div style="position:absolute;left:5.00px;top:294.75px" class="cls_004"><span class="cls_004">previous example, this can be useful while developing more complicated layouts. However,</span></div>
<div style="position:absolute;left:5.00px;top:312.75px" class="cls_004"><span class="cls_004">due to its poor performance, this feature should never be utilized in production XAML.</span></div>
<div style="position:absolute;left:52.98px;top:336.00px" class="cls_007"><span class="cls_007"><Grid TextElement.FontSize="14" Margin="10" ShowGridLines="True"></span></div>
<div style="position:absolute;left:52.98px;top:363.00px" class="cls_007"><span class="cls_007"></Grid></span></div>
<div style="position:absolute;left:5.00px;top:562.50px" class="cls_004"><span class="cls_004">The other useful property is the </span><span class="cls_007">IsSharedSizeScope</span><span class="cls_004"> Attached Property, which enables us to</span></div>
<div style="position:absolute;left:5.00px;top:580.50px" class="cls_004"><span class="cls_004">share sizing information between two or more </span><span class="cls_007">Grid</span><span class="cls_004"> panels. We can achieve this by setting</span></div>
<div style="position:absolute;left:5.00px;top:598.50px" class="cls_004"><span class="cls_004">this property to </span><span class="cls_007">true</span><span class="cls_004"> on a parent panel and then specifying the </span><span class="cls_007">SharedSizeGroup</span><span class="cls_004"> property</span></div>
<div style="position:absolute;left:5.00px;top:616.50px" class="cls_004"><span class="cls_004">on the relevant </span><span class="cls_007">ColumnDefinition</span><span class="cls_004"> and/or </span><span class="cls_007">RowDefinition</span><span class="cls_004"> elements of the inner </span><span class="cls_007">Grid</span><span class="cls_004"> panels.</span></div>
<div style="position:absolute;left:5.00px;top:634.50px" class="cls_004"><span class="cls_004">There are a few conditions that we need to adhere to in order to get this to work and the</span></div>
<div style="position:absolute;left:5.00px;top:652.50px" class="cls_004"><span class="cls_004">first relates to scope. The </span><span class="cls_007">IsSharedSizeScope</span><span class="cls_004"> Property need to be set on a parent</span></div>
<div style="position:absolute;left:5.00px;top:670.50px" class="cls_004"><span class="cls_004">element, but if that parent element is within a resource template and the definition elements</span></div>
<div style="position:absolute;left:5.00px;top:688.50px" class="cls_004"><span class="cls_004">that specify the </span><span class="cls_007">SharedSizeGroup</span><span class="cls_004"> property are outside that template then it will not work. It</span></div>
<div style="position:absolute;left:5.00px;top:706.50px" class="cls_004"><span class="cls_004">will however, work in the opposite direction.</span></div>
<div style="position:absolute;left:5.00px;top:724.50px" class="cls_004"><span class="cls_004">The other point to be aware of is that star-sizing is not respected when sharing sizing</span></div>
<div style="position:absolute;left:5.00px;top:742.50px" class="cls_004"><span class="cls_004">information. In these cases, the star values of any definition elements will be read as </span><span class="cls_007">Auto</span><span class="cls_004">,</span></div>
<div style="position:absolute;left:5.00px;top:760.50px" class="cls_004"><span class="cls_004">so we do not typically set the </span><span class="cls_007">SharedSizeGroup</span><span class="cls_004"> property on our star-sized column.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:140350px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background177.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">However, if we set it on the other columns, then we will be left with our desired layout. Let's</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">see an example of this:</span></div>
<div style="position:absolute;left:52.98px;top:45.00px" class="cls_007"><span class="cls_007"><Grid TextElement.FontSize="14" Margin="10"</span></div>
<div style="position:absolute;left:52.98px;top:58.50px" class="cls_007"><span class="cls_007">IsSharedSizeScope="True"></span></div>
<div style="position:absolute;left:67.97px;top:72.00px" class="cls_007"><span class="cls_007"><Grid.RowDefinitions></span></div>
<div style="position:absolute;left:82.97px;top:85.50px" class="cls_007"><span class="cls_007"><RowDefinition Height="Auto" /></span></div>
<div style="position:absolute;left:82.97px;top:99.00px" class="cls_007"><span class="cls_007"><RowDefinition Height="Auto" /></span></div>
<div style="position:absolute;left:82.97px;top:112.50px" class="cls_007"><span class="cls_007"><RowDefinition /></span></div>
<div style="position:absolute;left:67.97px;top:126.00px" class="cls_007"><span class="cls_007"></Grid.RowDefinitions></span></div>
<div style="position:absolute;left:67.97px;top:139.50px" class="cls_007"><span class="cls_007"><Grid TextElement.FontWeight="SemiBold" Margin="0,0,0,3"</span></div>
<div style="position:absolute;left:82.97px;top:153.00px" class="cls_007"><span class="cls_007">ShowGridLines="True"></span></div>
<div style="position:absolute;left:82.97px;top:166.50px" class="cls_007"><span class="cls_007"><Grid.ColumnDefinitions></span></div>
<div style="position:absolute;left:97.96px;top:180.00px" class="cls_007"><span class="cls_007"><ColumnDefinition Width="Auto" SharedSizeGroup="Name" /></span></div>
<div style="position:absolute;left:97.96px;top:193.50px" class="cls_007"><span class="cls_007"><ColumnDefinition /></span></div>
<div style="position:absolute;left:97.96px;top:207.00px" class="cls_007"><span class="cls_007"><ColumnDefinition Width="Auto" SharedSizeGroup="Age" /></span></div>
<div style="position:absolute;left:82.97px;top:220.50px" class="cls_007"><span class="cls_007"></Grid.ColumnDefinitions></span></div>
<div style="position:absolute;left:82.97px;top:234.00px" class="cls_007"><span class="cls_007"><TextBlock Text="Name" /></span></div>
<div style="position:absolute;left:82.97px;top:247.50px" class="cls_007"><span class="cls_007"><TextBlock Grid.Column="1" Text="Comments" Margin="10,0" /></span></div>
<div style="position:absolute;left:82.97px;top:261.00px" class="cls_007"><span class="cls_007"><TextBlock Grid.Column="2" Text="Age" /></span></div>
<div style="position:absolute;left:67.97px;top:274.50px" class="cls_007"><span class="cls_007"></Grid></span></div>
<div style="position:absolute;left:67.97px;top:288.00px" class="cls_007"><span class="cls_007"><Separator Grid.Row="1" /></span></div>
<div style="position:absolute;left:67.97px;top:301.50px" class="cls_007"><span class="cls_007"><ItemsControl Grid.Row="2" ItemsSource="{Binding Users}"></span></div>
<div style="position:absolute;left:82.97px;top:315.00px" class="cls_007"><span class="cls_007"><ItemsControl.ItemTemplate></span></div>
<div style="position:absolute;left:97.96px;top:328.50px" class="cls_007"><span class="cls_007"><DataTemplate DataType="{x:Type DataModels:User}"></span></div>
<div style="position:absolute;left:112.96px;top:342.00px" class="cls_007"><span class="cls_007"><Grid ShowGridLines="True"></span></div>
<div style="position:absolute;left:127.95px;top:355.50px" class="cls_007"><span class="cls_007"><Grid.ColumnDefinitions></span></div>
<div style="position:absolute;left:142.94px;top:369.00px" class="cls_007"><span class="cls_007"><ColumnDefinition Width="Auto" SharedSizeGroup="Name"</span></div>
<div style="position:absolute;left:52.98px;top:382.50px" class="cls_007"><span class="cls_007">/></span></div>
<div style="position:absolute;left:142.94px;top:396.00px" class="cls_007"><span class="cls_007"><ColumnDefinition /></span></div>
<div style="position:absolute;left:142.94px;top:409.50px" class="cls_007"><span class="cls_007"><ColumnDefinition Width="Auto" SharedSizeGroup="Age" /></span></div>
<div style="position:absolute;left:127.95px;top:423.00px" class="cls_007"><span class="cls_007"></Grid.ColumnDefinitions></span></div>
<div style="position:absolute;left:127.95px;top:436.50px" class="cls_007"><span class="cls_007"><TextBlock Text="{Binding Name}" /></span></div>
<div style="position:absolute;left:127.95px;top:450.00px" class="cls_007"><span class="cls_007"><TextBlock Grid.Column="1" Text="Star-sized column takes</span></div>
<div style="position:absolute;left:52.98px;top:463.50px" class="cls_007"><span class="cls_007">all</span></div>
<div style="position:absolute;left:142.94px;top:477.00px" class="cls_007"><span class="cls_007">remaining space" Margin="10,0" /></span></div>
<div style="position:absolute;left:127.95px;top:490.50px" class="cls_007"><span class="cls_007"><TextBlock Grid.Column="2" Text="{Binding Age}" /></span></div>
<div style="position:absolute;left:112.96px;top:504.00px" class="cls_007"><span class="cls_007"></Grid></span></div>
<div style="position:absolute;left:97.96px;top:517.50px" class="cls_007"><span class="cls_007"></DataTemplate></span></div>
<div style="position:absolute;left:82.97px;top:531.00px" class="cls_007"><span class="cls_007"></ItemsControl.ItemTemplate></span></div>
<div style="position:absolute;left:67.97px;top:544.50px" class="cls_007"><span class="cls_007"></ItemsControl></span></div>
<div style="position:absolute;left:52.98px;top:558.00px" class="cls_007"><span class="cls_007"></Grid></span></div>
<div style="position:absolute;left:5.00px;top:591.00px" class="cls_004"><span class="cls_004">In this example, we have an </span><span class="cls_007">ItemsControl</span><span class="cls_004"> that is data bound to a slightly edited version of</span></div>
<div style="position:absolute;left:5.00px;top:609.00px" class="cls_004"><span class="cls_004">our </span><span class="cls_007">Users</span><span class="cls_004"> collection from our earlier examples. Previously, all of the user names were of a</span></div>
<div style="position:absolute;left:5.00px;top:627.00px" class="cls_004"><span class="cls_004">similar length, so one has been edited to demonstrate this point more clearly. The</span></div>
<div style="position:absolute;left:5.00px;top:645.00px" class="cls_007"><span class="cls_007">ShowGridLines</span><span class="cls_004"> property has also been set to </span><span class="cls_007">true</span><span class="cls_004"> on the inner panels for the same reason.</span></div>
<div style="position:absolute;left:5.00px;top:663.00px" class="cls_004"><span class="cls_004">In the example, we first set the </span><span class="cls_007">IsSharedSizeScope</span><span class="cls_004"> Attached Property to </span><span class="cls_007">true</span><span class="cls_004"> on the</span></div>
<div style="position:absolute;left:5.00px;top:681.00px" class="cls_004"><span class="cls_004">parent </span><span class="cls_007">Grid</span><span class="cls_004"> panel and then apply the </span><span class="cls_007">SharedSizeGroup</span><span class="cls_004"> property to the definitions of the</span></div>
<div style="position:absolute;left:5.00px;top:699.00px" class="cls_004"><span class="cls_004">inner </span><span class="cls_007">Grid</span><span class="cls_004"> controls, that are declared inside the outer panel and within the </span><span class="cls_007">DataTemplate</span></div>
<div style="position:absolute;left:5.00px;top:717.00px" class="cls_004"><span class="cls_004">element. Let's see the rendered output of this code before continuing:</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:141152px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background178.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:151.50px" class="cls_004"><span class="cls_004">Note that we have provided the same number of columns and group names for the columns</span></div>
<div style="position:absolute;left:5.00px;top:169.50px" class="cls_004"><span class="cls_004">inside and outside of the </span><span class="cls_007">DataTemplate</span><span class="cls_004"> element, which is essential for this functionality to</span></div>
<div style="position:absolute;left:5.00px;top:187.50px" class="cls_004"><span class="cls_004">work. Also note that we have not set the </span><span class="cls_007">SharedSizeGroup</span><span class="cls_004"> property on the middle column,</span></div>
<div style="position:absolute;left:5.00px;top:205.50px" class="cls_004"><span class="cls_004">which is star-sized.</span></div>
<div style="position:absolute;left:5.00px;top:223.50px" class="cls_004"><span class="cls_004">Grouping just the other two columns will have the same visual effect as grouping all three,</span></div>
<div style="position:absolute;left:5.00px;top:241.50px" class="cls_004"><span class="cls_004">but without losing the star-sizing on the middle column. However, let's see what would</span></div>
<div style="position:absolute;left:5.00px;top:259.50px" class="cls_004"><span class="cls_004">happen if we also set the </span><span class="cls_007">SharedSizeGroup</span><span class="cls_004"> property on the middle column definitions.</span></div>
<div style="position:absolute;left:52.98px;top:282.75px" class="cls_007"><span class="cls_007"><ColumnDefinition SharedSizeGroup="Comments" /></span></div>
<div style="position:absolute;left:5.00px;top:303.00px" class="cls_004"><span class="cls_004">As expected, we have lost the star-sizing on our middle column and the remaining space</span></div>
<div style="position:absolute;left:5.00px;top:321.00px" class="cls_004"><span class="cls_004">has now been applied to the last column.</span></div>
<div style="position:absolute;left:5.00px;top:486.00px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">Grid</span><span class="cls_004"> panel within the template will be rendered for each item in the collection and so</span></div>
<div style="position:absolute;left:5.00px;top:504.00px" class="cls_004"><span class="cls_004">this will actually result in several panels, each with the same group names and therefore,</span></div>
<div style="position:absolute;left:5.00px;top:522.00px" class="cls_004"><span class="cls_004">also column spacing. It is important that we set the </span><span class="cls_007">IsSharedSizeScope</span><span class="cls_004"> property to </span><span class="cls_007">true</span><span class="cls_004"> on</span></div>
<div style="position:absolute;left:5.00px;top:540.00px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">Grid</span><span class="cls_004"> panel that is the common parent to all of the inner panels that we wish to share</span></div>
<div style="position:absolute;left:5.00px;top:558.00px" class="cls_004"><span class="cls_004">sizing information between.</span></div>
<div style="position:absolute;left:5.00px;top:575.25px" class="cls_013"><span class="cls_013">StackPanel</span></div>
<div style="position:absolute;left:5.00px;top:600.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">StackPanel</span><span class="cls_004"> is one of the WPF panels that only provides limited resizing abilities to its</span></div>
<div style="position:absolute;left:5.00px;top:618.75px" class="cls_004"><span class="cls_004">child items. It will automatically set the </span><span class="cls_007">HorizontalAlignment</span><span class="cls_004"> and </span><span class="cls_007">VerticalAlignment</span></div>
<div style="position:absolute;left:5.00px;top:636.75px" class="cls_004"><span class="cls_004">properties of each of its children to </span><span class="cls_007">Stretch</span><span class="cls_004">, as long as they don't have explicit sizes</span></div>
<div style="position:absolute;left:5.00px;top:654.75px" class="cls_004"><span class="cls_004">specified. In these cases alone, the child elements will be stretched to fit the size of the</span></div>
<div style="position:absolute;left:5.00px;top:672.75px" class="cls_004"><span class="cls_004">containing panel. This can be easily demonstrated.</span></div>
<div style="position:absolute;left:52.98px;top:696.00px" class="cls_007"><span class="cls_007"><Border Background="Black" Padding="5"></span></div>
<div style="position:absolute;left:67.97px;top:709.50px" class="cls_007"><span class="cls_007"><Border.Resources></span></div>
<div style="position:absolute;left:82.97px;top:723.00px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type TextBlock}"></span></div>
<div style="position:absolute;left:97.96px;top:736.50px" class="cls_007"><span class="cls_007"><Setter Property="Padding" Value="5" /></span></div>
<div style="position:absolute;left:97.96px;top:750.00px" class="cls_007"><span class="cls_007"><Setter Property="Background" Value="Yellow" /></span></div>
<div style="position:absolute;left:97.96px;top:763.50px" class="cls_007"><span class="cls_007"><Setter Property="TextAlignment" Value="Center" /></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:141954px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background179.jpg" width=612 height=792></div>
<div style="position:absolute;left:82.97px;top:3.00px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:67.97px;top:16.50px" class="cls_007"><span class="cls_007"></Border.Resources></span></div>
<div style="position:absolute;left:67.97px;top:30.00px" class="cls_007"><span class="cls_007"><StackPanel TextElement.FontSize="14"></span></div>
<div style="position:absolute;left:82.97px;top:43.50px" class="cls_007"><span class="cls_007"><TextBlock Text="Stretched Horizontally" /></span></div>
<div style="position:absolute;left:82.97px;top:57.00px" class="cls_007"><span class="cls_007"><TextBlock Text="With Margin" Margin="20" /></span></div>
<div style="position:absolute;left:82.97px;top:70.50px" class="cls_007"><span class="cls_007"><TextBlock Text="Centered
Horizontally"</span></div>
<div style="position:absolute;left:97.96px;top:84.00px" class="cls_007"><span class="cls_007">HorizontalAlignment="Center" /></span></div>
<div style="position:absolute;left:82.97px;top:97.50px" class="cls_007"><span class="cls_007"><Border BorderBrush="Cyan" BorderThickness="1" Margin="0,5,0,0"</span></div>
<div style="position:absolute;left:97.96px;top:111.00px" class="cls_007"><span class="cls_007">Padding="5" SnapsToDevicePixels="True"></span></div>
<div style="position:absolute;left:97.96px;top:124.50px" class="cls_007"><span class="cls_007"><StackPanel Orientation="Horizontal"></span></div>
<div style="position:absolute;left:112.96px;top:138.00px" class="cls_007"><span class="cls_007"><TextBlock Text="Stretched
Vertically" /></span></div>
<div style="position:absolute;left:112.96px;top:151.50px" class="cls_007"><span class="cls_007"><TextBlock Text="With Margin" Margin="20" /></span></div>
<div style="position:absolute;left:112.96px;top:165.00px" class="cls_007"><span class="cls_007"><TextBlock Text="Centered
Vertically"</span></div>
<div style="position:absolute;left:127.95px;top:178.50px" class="cls_007"><span class="cls_007">VerticalAlignment="Center" /></span></div>
<div style="position:absolute;left:97.96px;top:192.00px" class="cls_007"><span class="cls_007"></StackPanel></span></div>
<div style="position:absolute;left:82.97px;top:205.50px" class="cls_007"><span class="cls_007"></Border></span></div>
<div style="position:absolute;left:67.97px;top:219.00px" class="cls_007"><span class="cls_007"></StackPanel></span></div>
<div style="position:absolute;left:52.98px;top:232.50px" class="cls_007"><span class="cls_007"></Border></span></div>
<div style="position:absolute;left:5.00px;top:252.75px" class="cls_004"><span class="cls_004">This panel literally lays each child element out one after the other, vertically by default, or</span></div>
<div style="position:absolute;left:5.00px;top:270.75px" class="cls_004"><span class="cls_004">horizontally when its </span><span class="cls_007">Orientation</span><span class="cls_004"> property is set to </span><span class="cls_007">Horizontal</span><span class="cls_004">. Our example uses both</span></div>
<div style="position:absolute;left:5.00px;top:288.75px" class="cls_004"><span class="cls_004">orientations, so let's take a quick look at its output before continuing:</span></div>
<div style="position:absolute;left:5.00px;top:533.25px" class="cls_004"><span class="cls_004">Our whole example is wrapped in a </span><span class="cls_007">Border</span><span class="cls_004"> element with a black background. In its</span></div>
<div style="position:absolute;left:5.00px;top:551.25px" class="cls_007"><span class="cls_007">Resources</span><span class="cls_004"> section, we declared a few style properties for the </span><span class="cls_007">TextBlock</span><span class="cls_004"> elements in our</span></div>
<div style="position:absolute;left:5.00px;top:569.25px" class="cls_004"><span class="cls_004">example. Inside the border, we declare our first </span><span class="cls_007">StackPanel</span><span class="cls_004"> control, with its default vertical</span></div>
<div style="position:absolute;left:5.00px;top:587.25px" class="cls_004"><span class="cls_004">orientation. In this first panel, we have three </span><span class="cls_007">TextBlock</span><span class="cls_004"> elements and another </span><span class="cls_007">StackPanel</span></div>
<div style="position:absolute;left:5.00px;top:605.25px" class="cls_004"><span class="cls_004">wrapped in a border.</span></div>
<div style="position:absolute;left:5.00px;top:623.25px" class="cls_004"><span class="cls_004">The first </span><span class="cls_007">TextBlock</span><span class="cls_004"> element is automatically stretched to fit the width of the panel. The</span></div>
<div style="position:absolute;left:5.00px;top:641.25px" class="cls_004"><span class="cls_004">second adds a margin, but would otherwise also be stretched across the width of the</span></div>
<div style="position:absolute;left:5.00px;top:659.25px" class="cls_004"><span class="cls_004">panel. The third however, has its </span><span class="cls_007">HorizontalAlignment</span><span class="cls_004"> property explicitly set to </span><span class="cls_007">Center</span><span class="cls_004"> and</span></div>
<div style="position:absolute;left:5.00px;top:677.25px" class="cls_004"><span class="cls_004">so it is not stretched to fit by the panel.</span></div>
<div style="position:absolute;left:5.00px;top:695.25px" class="cls_004"><span class="cls_004">The inner panel has three </span><span class="cls_007">TextBlock</span><span class="cls_004"> elements declared inside it and has its </span><span class="cls_007">Orientation</span></div>
<div style="position:absolute;left:5.00px;top:713.25px" class="cls_004"><span class="cls_004">property set to </span><span class="cls_007">Horizontal</span><span class="cls_004">. Its children are therefore laid out horizontally. Its border is</span></div>
<div style="position:absolute;left:5.00px;top:731.25px" class="cls_004"><span class="cls_004">colored, so that it is easier to see its bounds. Note the use of the </span><span class="cls_007">SnapsToDevicePixels</span></div>
<div style="position:absolute;left:5.00px;top:749.25px" class="cls_004"><span class="cls_004">property set on it.</span></div>
<div style="position:absolute;left:5.00px;top:767.25px" class="cls_004"><span class="cls_004">As WPF uses device-independent pixel settings, thin straight lines can sometimes lie across</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:142756px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background180.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">individual pixel boundaries and appear anti-aliased. Setting this property to </span><span class="cls_007">true</span><span class="cls_004"> will force</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">the element to be rendered exactly in line with the physical pixels, using device-specific pixel</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">settings and forming a clearer, sharper line.</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">The first </span><span class="cls_007">TextBlock</span><span class="cls_004"> element in the lower panel is automatically stretched to fit the height of</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">the panel. As with the elements in the upper panel, the second adds a margin, but would</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">otherwise also be stretched across the height of the panel. The third however, has its</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_007"><span class="cls_007">VerticalAlignment</span><span class="cls_004"> property explicitly set to </span><span class="cls_007">Center</span><span class="cls_004"> and so it is not stretched vertically to fit</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">by the panel.</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">As a side note, we have used the hexadecimal </span><span class="cls_007">
</span><span class="cls_004"> entity to add a new line in some of</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">our text strings. This could also have been achieved using the </span><span class="cls_007">TextBlock.TextWrapping</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">property and hard coding a </span><span class="cls_007">Width</span><span class="cls_004"> for each element, but this way is obviously far simpler.</span></div>
<div style="position:absolute;left:5.00px;top:201.00px" class="cls_013"><span class="cls_013">UniformGrid</span></div>
<div style="position:absolute;left:5.00px;top:226.50px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">UniformGrid</span><span class="cls_004"> panel is a lightweight panel that provides a simple way to create a grid of</span></div>
<div style="position:absolute;left:5.00px;top:244.50px" class="cls_004"><span class="cls_004">items, where each item is of the same size. We can set its </span><span class="cls_007">Row</span><span class="cls_004"> and </span><span class="cls_007">Column</span><span class="cls_004"> properties to</span></div>
<div style="position:absolute;left:5.00px;top:262.50px" class="cls_004"><span class="cls_004">specify how many rows and columns that we want our grid to have. If we do not set one or</span></div>
<div style="position:absolute;left:5.00px;top:280.50px" class="cls_004"><span class="cls_004">both of these properties, the panel will implicitly set them for us, dependent upon the</span></div>
<div style="position:absolute;left:5.00px;top:298.50px" class="cls_004"><span class="cls_004">available space it has and the size of its children.</span></div>
<div style="position:absolute;left:5.00px;top:316.50px" class="cls_004"><span class="cls_004">It also provides us with a </span><span class="cls_007">FirstColumn</span><span class="cls_004"> property that will affect the column that the first child</span></div>
<div style="position:absolute;left:5.00px;top:334.50px" class="cls_004"><span class="cls_004">item will be rendered in. For example, if we set this property to </span><span class="cls_007">2</span><span class="cls_004"> then the first child will be</span></div>
<div style="position:absolute;left:5.00px;top:352.50px" class="cls_004"><span class="cls_004">rendered in the third column. This is perfect for a calendar control, so let's take a look at</span></div>
<div style="position:absolute;left:5.00px;top:370.50px" class="cls_004"><span class="cls_004">how we might create the following output using the </span><span class="cls_007">UniformGrid</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:620.25px" class="cls_004"><span class="cls_004">As you can see, a calendar control often needs to have blank spaces in the first few</span></div>
<div style="position:absolute;left:5.00px;top:638.25px" class="cls_004"><span class="cls_004">columns and so the </span><span class="cls_007">FirstColumn</span><span class="cls_004"> property achieves this requirement simply. Let's see the</span></div>
<div style="position:absolute;left:5.00px;top:656.25px" class="cls_004"><span class="cls_004">XAML that defines this calendar example:</span></div>
<div style="position:absolute;left:52.98px;top:679.50px" class="cls_007"><span class="cls_007"><StackPanel TextElement.FontSize="14" Background="White"></span></div>
<div style="position:absolute;left:67.97px;top:693.00px" class="cls_007"><span class="cls_007"><UniformGrid Columns="7" Rows="1"></span></div>
<div style="position:absolute;left:82.97px;top:706.50px" class="cls_007"><span class="cls_007"><UniformGrid.Resources></span></div>
<div style="position:absolute;left:97.96px;top:720.00px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type TextBlock}"></span></div>
<div style="position:absolute;left:112.96px;top:733.50px" class="cls_007"><span class="cls_007"><Setter Property="Height" Value="35" /></span></div>
<div style="position:absolute;left:112.96px;top:747.00px" class="cls_007"><span class="cls_007"><Setter Property="HorizontalAlignment" Value="Center" /></span></div>
<div style="position:absolute;left:112.96px;top:760.50px" class="cls_007"><span class="cls_007"><Setter Property="Padding" Value="0,5,0,0" /></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:143558px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background181.jpg" width=612 height=792></div>
<div style="position:absolute;left:97.96px;top:3.00px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:82.97px;top:16.50px" class="cls_007"><span class="cls_007"></UniformGrid.Resources></span></div>
<div style="position:absolute;left:82.97px;top:30.00px" class="cls_007"><span class="cls_007"><TextBlock Text="Mon" /></span></div>
<div style="position:absolute;left:82.97px;top:43.50px" class="cls_007"><span class="cls_007"><TextBlock Text="Tue" /></span></div>
<div style="position:absolute;left:82.97px;top:57.00px" class="cls_007"><span class="cls_007"><TextBlock Text="Wed" /></span></div>
<div style="position:absolute;left:82.97px;top:70.50px" class="cls_007"><span class="cls_007"><TextBlock Text="Thu" /></span></div>
<div style="position:absolute;left:82.97px;top:84.00px" class="cls_007"><span class="cls_007"><TextBlock Text="Fri" /></span></div>
<div style="position:absolute;left:82.97px;top:97.50px" class="cls_007"><span class="cls_007"><TextBlock Text="Sat" /></span></div>
<div style="position:absolute;left:82.97px;top:111.00px" class="cls_007"><span class="cls_007"><TextBlock Text="Sun" /></span></div>
<div style="position:absolute;left:67.97px;top:124.50px" class="cls_007"><span class="cls_007"></UniformGrid></span></div>
<div style="position:absolute;left:67.97px;top:138.00px" class="cls_007"><span class="cls_007"><ItemsControl ItemsSource="{Binding Days}" Background="Black"></span></div>
<div style="position:absolute;left:82.97px;top:151.50px" class="cls_007"><span class="cls_007"><ItemsControl.ItemsPanel></span></div>
<div style="position:absolute;left:97.96px;top:165.00px" class="cls_007"><span class="cls_007"><ItemsPanelTemplate></span></div>
<div style="position:absolute;left:112.96px;top:178.50px" class="cls_007"><span class="cls_007"><UniformGrid Columns="7" FirstColumn="2" /></span></div>
<div style="position:absolute;left:97.96px;top:192.00px" class="cls_007"><span class="cls_007"></ItemsPanelTemplate></span></div>
<div style="position:absolute;left:82.97px;top:205.50px" class="cls_007"><span class="cls_007"></ItemsControl.ItemsPanel></span></div>
<div style="position:absolute;left:82.97px;top:219.00px" class="cls_007"><span class="cls_007"><ItemsControl.ItemTemplate></span></div>
<div style="position:absolute;left:97.96px;top:232.50px" class="cls_007"><span class="cls_007"><DataTemplate></span></div>
<div style="position:absolute;left:112.96px;top:246.00px" class="cls_007"><span class="cls_007"><Border BorderBrush="Black" BorderThickness="1,1,0,0"</span></div>
<div style="position:absolute;left:127.95px;top:259.50px" class="cls_007"><span class="cls_007">Background="White"></span></div>
<div style="position:absolute;left:127.95px;top:273.00px" class="cls_007"><span class="cls_007"><TextBlock Text="{Binding}" Height="35"</span></div>
<div style="position:absolute;left:142.94px;top:286.50px" class="cls_007"><span class="cls_007">HorizontalAlignment="Center" Padding="0,7.5,0,0" /></span></div>
<div style="position:absolute;left:112.96px;top:300.00px" class="cls_007"><span class="cls_007"></Border></span></div>
<div style="position:absolute;left:97.96px;top:313.50px" class="cls_007"><span class="cls_007"></DataTemplate></span></div>
<div style="position:absolute;left:82.97px;top:327.00px" class="cls_007"><span class="cls_007"></ItemsControl.ItemTemplate></span></div>
<div style="position:absolute;left:67.97px;top:340.50px" class="cls_007"><span class="cls_007"></ItemsControl></span></div>
<div style="position:absolute;left:52.98px;top:354.00px" class="cls_007"><span class="cls_007"></StackPanel></span></div>
<div style="position:absolute;left:5.00px;top:374.25px" class="cls_004"><span class="cls_004">We start with a </span><span class="cls_007">StackPanel</span><span class="cls_004"> that is used to stack one </span><span class="cls_007">UniformGrid</span><span class="cls_004"> panel directly above an</span></div>
<div style="position:absolute;left:5.00px;top:392.25px" class="cls_007"><span class="cls_007">ItemsControl</span><span class="cls_004"> that uses another one as its </span><span class="cls_007">ItemsPanel</span><span class="cls_004"> and specifies a font size to use</span></div>
<div style="position:absolute;left:5.00px;top:410.25px" class="cls_004"><span class="cls_004">within the control. The top </span><span class="cls_007">UniformGrid</span><span class="cls_004"> panel declares a single row of seven columns and</span></div>
<div style="position:absolute;left:5.00px;top:428.25px" class="cls_004"><span class="cls_004">some basic </span><span class="cls_007">TextBlock</span><span class="cls_004"> styles. It has seven child </span><span class="cls_007">TextBlock</span><span class="cls_004"> items, that output the names of</span></div>
<div style="position:absolute;left:5.00px;top:446.25px" class="cls_004"><span class="cls_004">the days in a week.</span></div>
<div style="position:absolute;left:5.00px;top:464.25px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">ItemsControl.ItemsSource</span><span class="cls_004"> is data bound to a </span><span class="cls_007">Days</span><span class="cls_004"> property in our View Model.</span></div>
<div style="position:absolute;left:52.98px;top:487.50px" class="cls_007"><span class="cls_007">private List<int> days = Enumerable.Range(1, 31).ToList();</span></div>
<div style="position:absolute;left:52.98px;top:541.50px" class="cls_007"><span class="cls_007">public List<int> Days</span></div>
<div style="position:absolute;left:52.98px;top:555.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:568.50px" class="cls_007"><span class="cls_007">get { return days; }</span></div>
<div style="position:absolute;left:67.97px;top:582.00px" class="cls_007"><span class="cls_007">set { days = value; NotifyPropertyChanged(); }</span></div>
<div style="position:absolute;left:52.98px;top:595.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:615.75px" class="cls_004"><span class="cls_004">Note the use of the </span><span class="cls_007">Enumerable.Range</span><span class="cls_004"> method to populate the collection. It provides a</span></div>
<div style="position:absolute;left:5.00px;top:633.75px" class="cls_004"><span class="cls_004">simple way to generate a contiguous sequence of integers from the supplied start and</span></div>
<div style="position:absolute;left:5.00px;top:651.75px" class="cls_004"><span class="cls_004">length input parameters. As a LINQ method, it is implemented using deferred execution and</span></div>
<div style="position:absolute;left:5.00px;top:669.75px" class="cls_004"><span class="cls_004">the actual values are not generated until actually accessed.</span></div>
<div style="position:absolute;left:5.00px;top:687.75px" class="cls_004"><span class="cls_004">The second </span><span class="cls_007">UniformGrid</span><span class="cls_004"> panel, that is set as the </span><span class="cls_007">ItemsControl.ItemsPanel</span><span class="cls_004">, only specifies</span></div>
<div style="position:absolute;left:5.00px;top:705.75px" class="cls_004"><span class="cls_004">that it should have seven columns, but leaves the number of rows to be calculated from the</span></div>
<div style="position:absolute;left:5.00px;top:723.75px" class="cls_004"><span class="cls_004">number of data bound items. Note also, that we have hard coded a value of </span><span class="cls_007">2</span><span class="cls_004"> to the</span></div>
<div style="position:absolute;left:5.00px;top:741.75px" class="cls_007"><span class="cls_007">FirstColumn</span><span class="cls_004"> property, although in a proper control, we would typically data bind the value</span></div>
<div style="position:absolute;left:5.00px;top:759.75px" class="cls_004"><span class="cls_004">for the relevant month to it instead.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:144360px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background182.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">Finally, we use a </span><span class="cls_007">DataTemplate</span><span class="cls_004"> to define what each day on the calendar should look like.</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">Note that we do not need to specify a value for its </span><span class="cls_007">DataType</span><span class="cls_004"> property in this example,</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">because we are data binding to the whole data source object, which in this case, is just an</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">integer. Let's now move on to investigate the </span><span class="cls_007">WrapPanel</span><span class="cls_004"> panel.</span></div>
<div style="position:absolute;left:5.00px;top:75.00px" class="cls_013"><span class="cls_013">WrapPanel</span></div>
<div style="position:absolute;left:5.00px;top:100.50px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">WrapPanel</span><span class="cls_004"> is similar to the </span><span class="cls_007">StackPanel</span><span class="cls_004">, except that it will stack its children in both</span></div>
<div style="position:absolute;left:5.00px;top:118.50px" class="cls_004"><span class="cls_004">directions by default. It starts by laying out the child items horizontally and when it runs out</span></div>
<div style="position:absolute;left:5.00px;top:136.50px" class="cls_004"><span class="cls_004">of space on the first row, it automatically wraps the next item onto a new row and continues</span></div>
<div style="position:absolute;left:5.00px;top:154.50px" class="cls_004"><span class="cls_004">to lay out the remaining controls. It repeats this process using as many rows as are</span></div>
<div style="position:absolute;left:5.00px;top:172.50px" class="cls_004"><span class="cls_004">required, until all of the items are rendered.</span></div>
<div style="position:absolute;left:5.00px;top:190.50px" class="cls_004"><span class="cls_004">However, it also provides an </span><span class="cls_007">Orientation</span><span class="cls_004"> property like the </span><span class="cls_007">StackPanel</span><span class="cls_004">, and this will affect</span></div>
<div style="position:absolute;left:5.00px;top:208.50px" class="cls_004"><span class="cls_004">its layout behavior. If the </span><span class="cls_007">Orientation</span><span class="cls_004"> property is changed from the default value of</span></div>
<div style="position:absolute;left:5.00px;top:226.50px" class="cls_007"><span class="cls_007">Horizontal</span><span class="cls_004"> to </span><span class="cls_007">Vertical</span><span class="cls_004">, then the panel's child items will be laid out vertically, from top to</span></div>
<div style="position:absolute;left:5.00px;top:244.50px" class="cls_004"><span class="cls_004">bottom until there is no more room in the first column. The items will then wrap to the next</span></div>
<div style="position:absolute;left:5.00px;top:262.50px" class="cls_004"><span class="cls_004">column and will continue in this way until all of the items have been rendered.</span></div>
<div style="position:absolute;left:5.00px;top:280.50px" class="cls_004"><span class="cls_004">This panel also declares </span><span class="cls_007">ItemHeight</span><span class="cls_004"> and </span><span class="cls_007">ItemWidth</span><span class="cls_004"> properties that enable it to restrict</span></div>
<div style="position:absolute;left:5.00px;top:298.50px" class="cls_004"><span class="cls_004">items' dimensions and to produce a layout behavior similar to the </span><span class="cls_007">UniformGrid</span><span class="cls_004"> panel. Note</span></div>
<div style="position:absolute;left:5.00px;top:316.50px" class="cls_004"><span class="cls_004">that the values will not actually resize each child item, but merely restrict the available</span></div>
<div style="position:absolute;left:5.00px;top:334.50px" class="cls_004"><span class="cls_004">space that they are provided with in the panel. Let's see an example of this:</span></div>
<div style="position:absolute;left:52.98px;top:357.75px" class="cls_007"><span class="cls_007"><WrapPanel ItemHeight="50" Width="150" TextElement.FontSize="14"></span></div>
<div style="position:absolute;left:67.97px;top:371.25px" class="cls_007"><span class="cls_007"><WrapPanel.Resources></span></div>
<div style="position:absolute;left:82.97px;top:384.75px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type Button}"></span></div>
<div style="position:absolute;left:97.96px;top:398.25px" class="cls_007"><span class="cls_007"><Setter Property="Width" Value="50" /></span></div>
<div style="position:absolute;left:82.97px;top:411.75px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:67.97px;top:425.25px" class="cls_007"><span class="cls_007"></WrapPanel.Resources></span></div>
<div style="position:absolute;left:67.97px;top:438.75px" class="cls_007"><span class="cls_007"><Button Content="7" /></span></div>
<div style="position:absolute;left:67.97px;top:452.25px" class="cls_007"><span class="cls_007"><Button Content="8" /></span></div>
<div style="position:absolute;left:67.97px;top:465.75px" class="cls_007"><span class="cls_007"><Button Content="9" /></span></div>
<div style="position:absolute;left:67.97px;top:479.25px" class="cls_007"><span class="cls_007"><Button Content="4" /></span></div>
<div style="position:absolute;left:67.97px;top:492.75px" class="cls_007"><span class="cls_007"><Button Content="5" /></span></div>
<div style="position:absolute;left:67.97px;top:506.25px" class="cls_007"><span class="cls_007"><Button Content="6" /></span></div>
<div style="position:absolute;left:67.97px;top:519.75px" class="cls_007"><span class="cls_007"><Button Content="1" /></span></div>
<div style="position:absolute;left:67.97px;top:533.25px" class="cls_007"><span class="cls_007"><Button Content="2" /></span></div>
<div style="position:absolute;left:67.97px;top:546.75px" class="cls_007"><span class="cls_007"><Button Content="3" /></span></div>
<div style="position:absolute;left:67.97px;top:560.25px" class="cls_007"><span class="cls_007"><Button Content="0" Width="100" /></span></div>
<div style="position:absolute;left:67.97px;top:573.75px" class="cls_007"><span class="cls_007"><Button Content="." /></span></div>
<div style="position:absolute;left:52.98px;top:587.25px" class="cls_007"><span class="cls_007"></WrapPanel></span></div>
<div style="position:absolute;left:5.00px;top:607.50px" class="cls_004"><span class="cls_004">Note that while similar to the output of a </span><span class="cls_007">UniformGrid</span><span class="cls_004"> panel, the output of this example</span></div>
<div style="position:absolute;left:5.00px;top:625.50px" class="cls_004"><span class="cls_004">could not actually be achieved with that panel, because one of the child items is a different</span></div>
<div style="position:absolute;left:5.00px;top:643.50px" class="cls_004"><span class="cls_004">size to the others. Let's see the visual output of this example.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:145162px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background183.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:224.25px" class="cls_004"><span class="cls_004">We first declare the </span><span class="cls_007">WrapPanel</span><span class="cls_004"> and specify that each child should only be provided with a</span></div>
<div style="position:absolute;left:5.00px;top:242.25px" class="cls_004"><span class="cls_004">height of </span><span class="cls_007">50</span><span class="cls_004"> pixels, while the panel itself should be </span><span class="cls_007">150</span><span class="cls_004"> pixels wide. In the </span><span class="cls_007">Resources</span></div>
<div style="position:absolute;left:5.00px;top:260.25px" class="cls_004"><span class="cls_004">section, we set the width of each button to be </span><span class="cls_007">50</span><span class="cls_004"> pixels wide, therefore enabling three</span></div>
<div style="position:absolute;left:5.00px;top:278.25px" class="cls_004"><span class="cls_004">buttons to sit next to each other on each row, before wrapping items to the next row.</span></div>
<div style="position:absolute;left:5.00px;top:296.25px" class="cls_004"><span class="cls_004">Next, we simply define the eleven buttons that make up the panel's children, specifying that</span></div>
<div style="position:absolute;left:5.00px;top:314.25px" class="cls_004"><span class="cls_004">the zero button should be twice as wide as the others. Note that this would not have</span></div>
<div style="position:absolute;left:5.00px;top:332.25px" class="cls_004"><span class="cls_004">worked if we had set the </span><span class="cls_007">ItemWidth</span><span class="cls_004"> property to </span><span class="cls_007">50</span><span class="cls_004"> pixels, along with the </span><span class="cls_007">ItemHeight</span></div>
<div style="position:absolute;left:5.00px;top:350.25px" class="cls_004"><span class="cls_004">property. In that case, we would have seen half of the zero button, with the other half</span></div>
<div style="position:absolute;left:5.00px;top:368.25px" class="cls_004"><span class="cls_004">covered by the period button and a blank space where the period button currently is.</span></div>
<div style="position:absolute;left:5.00px;top:385.50px" class="cls_013"><span class="cls_013">Providing custom layout behavior</span></div>
<div style="position:absolute;left:5.00px;top:411.00px" class="cls_004"><span class="cls_004">When the layout behavior of the built-in panels do not meet our requirements, we can easily</span></div>
<div style="position:absolute;left:5.00px;top:429.00px" class="cls_004"><span class="cls_004">define a new panel with custom layout behavior. All we need to do is declare a class that</span></div>
<div style="position:absolute;left:5.00px;top:447.00px" class="cls_004"><span class="cls_004">extends the </span><span class="cls_007">Panel</span><span class="cls_004"> class and override its </span><span class="cls_007">MeasureOverride</span><span class="cls_004"> and </span><span class="cls_007">ArrangeOverride</span><span class="cls_004"> methods.</span></div>
<div style="position:absolute;left:5.00px;top:465.00px" class="cls_004"><span class="cls_004">In the </span><span class="cls_007">MeasureOverride</span><span class="cls_004"> method, we simply call the </span><span class="cls_007">Measure</span><span class="cls_004"> method on each child item from</span></div>
<div style="position:absolute;left:5.00px;top:483.00px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">Children</span><span class="cls_004"> collection, passing in a </span><span class="cls_007">Size</span><span class="cls_004"> element set to </span><span class="cls_007">double.PositiveInfinity</span><span class="cls_004">. This is</span></div>
<div style="position:absolute;left:5.00px;top:501.00px" class="cls_004"><span class="cls_004">equivalent to saying "set your </span><span class="cls_007">DesriredSize</span><span class="cls_004"> property as if you had all of the space that you</span></div>
<div style="position:absolute;left:5.00px;top:519.00px" class="cls_004"><span class="cls_004">could possibly need" to each child item.</span></div>
<div style="position:absolute;left:5.00px;top:537.00px" class="cls_004"><span class="cls_004">In the </span><span class="cls_007">ArrangeOverride</span><span class="cls_004"> method, we use the newly determined </span><span class="cls_007">DesriredSize</span><span class="cls_004"> property value</span></div>
<div style="position:absolute;left:5.00px;top:555.00px" class="cls_004"><span class="cls_004">of each child item to calculate its required position and call its </span><span class="cls_007">Arrange</span><span class="cls_004"> method to render it</span></div>
<div style="position:absolute;left:5.00px;top:573.00px" class="cls_004"><span class="cls_004">in that position. Let's look at an example of a custom panel that positions its items equally</span></div>
<div style="position:absolute;left:5.00px;top:591.00px" class="cls_004"><span class="cls_004">around the circumference of a circle.</span></div>
<div style="position:absolute;left:52.98px;top:614.25px" class="cls_007"><span class="cls_007">using System;</span></div>
<div style="position:absolute;left:52.98px;top:627.75px" class="cls_007"><span class="cls_007">using System.Windows;</span></div>
<div style="position:absolute;left:52.98px;top:641.25px" class="cls_007"><span class="cls_007">using System.Windows.Controls;</span></div>
<div style="position:absolute;left:52.98px;top:668.25px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.Views.Panels</span></div>
<div style="position:absolute;left:52.98px;top:681.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:695.25px" class="cls_007"><span class="cls_007">public class CircumferencePanel : Panel</span></div>
<div style="position:absolute;left:67.97px;top:708.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:722.25px" class="cls_007"><span class="cls_007">public Thickness Padding { get; set; }</span></div>
<div style="position:absolute;left:82.97px;top:749.25px" class="cls_007"><span class="cls_007">protected override Size MeasureOverride(Size availableSize)</span></div>
<div style="position:absolute;left:82.97px;top:762.75px" class="cls_007"><span class="cls_007">{</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:145964px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background184.jpg" width=612 height=792></div>
<div style="position:absolute;left:97.96px;top:3.00px" class="cls_007"><span class="cls_007">foreach (UIElement element in Children)</span></div>
<div style="position:absolute;left:97.96px;top:16.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:112.96px;top:30.00px" class="cls_007"><span class="cls_007">element.Measure(</span></div>
<div style="position:absolute;left:127.95px;top:43.50px" class="cls_007"><span class="cls_007">new Size(double.PositiveInfinity,</span></div>
<div style="position:absolute;left:52.98px;top:57.00px" class="cls_007"><span class="cls_007">double.PositiveInfinity));</span></div>
<div style="position:absolute;left:97.96px;top:70.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:97.96px;top:84.00px" class="cls_007"><span class="cls_007">return availableSize;</span></div>
<div style="position:absolute;left:82.97px;top:97.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:124.50px" class="cls_007"><span class="cls_007">protected override Size ArrangeOverride(Size finalSize)</span></div>
<div style="position:absolute;left:82.97px;top:138.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:151.50px" class="cls_007"><span class="cls_007">if (Children.Count == 0) return finalSize;</span></div>
<div style="position:absolute;left:97.96px;top:165.00px" class="cls_007"><span class="cls_007">double currentAngle = 90 * (Math.PI / 180);</span></div>
<div style="position:absolute;left:97.96px;top:178.50px" class="cls_007"><span class="cls_007">double radiansPerElement =</span></div>
<div style="position:absolute;left:112.96px;top:192.00px" class="cls_007"><span class="cls_007">(360 / Children.Count) * (Math.PI / 180.0);</span></div>
<div style="position:absolute;left:97.96px;top:205.50px" class="cls_007"><span class="cls_007">double radiusX = finalSize.Width / 2.0 - Padding.Left;</span></div>
<div style="position:absolute;left:97.96px;top:219.00px" class="cls_007"><span class="cls_007">double radiusY = finalSize.Height / 2.0 - Padding.Top;</span></div>
<div style="position:absolute;left:97.96px;top:232.50px" class="cls_007"><span class="cls_007">foreach (UIElement element in Children)</span></div>
<div style="position:absolute;left:97.96px;top:246.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:112.96px;top:259.50px" class="cls_007"><span class="cls_007">Point childPoint = new Point(Math.Cos(currentAngle) *</span></div>
<div style="position:absolute;left:52.98px;top:273.00px" class="cls_007"><span class="cls_007">radiusX,</span></div>
<div style="position:absolute;left:127.95px;top:286.50px" class="cls_007"><span class="cls_007">-Math.Sin(currentAngle) * radiusY);</span></div>
<div style="position:absolute;left:112.96px;top:300.00px" class="cls_007"><span class="cls_007">Point centeredChildPoint = new Point(childPoint.X +</span></div>
<div style="position:absolute;left:127.95px;top:313.50px" class="cls_007"><span class="cls_007">finalSize.Width / 2 - element.DesiredSize.Width / 2,</span></div>
<div style="position:absolute;left:52.98px;top:327.00px" class="cls_007"><span class="cls_007">childPoint.Y</span></div>
<div style="position:absolute;left:127.95px;top:340.50px" class="cls_007"><span class="cls_007">+ finalSize.Height / 2 - element.DesiredSize.Height / 2);</span></div>
<div style="position:absolute;left:112.96px;top:354.00px" class="cls_007"><span class="cls_007">Rect boundingBox =</span></div>
<div style="position:absolute;left:127.95px;top:367.50px" class="cls_007"><span class="cls_007">new Rect(centeredChildPoint, element.DesiredSize);</span></div>
<div style="position:absolute;left:112.96px;top:381.00px" class="cls_007"><span class="cls_007">element.Arrange(boundingBox);</span></div>
<div style="position:absolute;left:112.96px;top:394.50px" class="cls_007"><span class="cls_007">currentAngle -= radiansPerElement;</span></div>
<div style="position:absolute;left:97.96px;top:408.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:97.96px;top:421.50px" class="cls_007"><span class="cls_007">return finalSize;</span></div>
<div style="position:absolute;left:82.97px;top:435.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:448.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:462.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:482.25px" class="cls_004"><span class="cls_004">In our </span><span class="cls_007">CircumferencePanel</span><span class="cls_004"> class, we first declare our own </span><span class="cls_007">Padding</span><span class="cls_004"> property of type</span></div>
<div style="position:absolute;left:5.00px;top:500.25px" class="cls_007"><span class="cls_007">Thickness</span><span class="cls_004">, which will be used to enable the users of the panel to lengthen or shorten the</span></div>
<div style="position:absolute;left:5.00px;top:518.25px" class="cls_004"><span class="cls_004">radius of the circle and therefore, adjust the position of the rendered items within the panel.</span></div>
<div style="position:absolute;left:5.00px;top:536.25px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">MeasureOverride</span><span class="cls_004"> method is a simple affair, as previously explained.</span></div>
<div style="position:absolute;left:5.00px;top:554.25px" class="cls_004"><span class="cls_004">In the </span><span class="cls_007">ArrangeOverride</span><span class="cls_004"> method, we calculate the relevant angles to position the child items</span></div>
<div style="position:absolute;left:5.00px;top:572.25px" class="cls_004"><span class="cls_004">with, depending upon how many of them there are. We take the value of our </span><span class="cls_007">Padding</span></div>
<div style="position:absolute;left:5.00px;top:590.25px" class="cls_004"><span class="cls_004">property into consideration when calculating the </span><span class="cls_006">X</span><span class="cls_004"> and </span><span class="cls_006">Y</span><span class="cls_004"> radiuses, so that users of our</span></div>
<div style="position:absolute;left:5.00px;top:609.00px" class="cls_004"><span class="cls_004">custom panel will be better able to control the position of the rendered items.</span></div>
<div style="position:absolute;left:5.00px;top:627.00px" class="cls_004"><span class="cls_004">For each child item in the panel's </span><span class="cls_007">Children</span><span class="cls_004"> collection, we first calculate the point on the</span></div>
<div style="position:absolute;left:5.00px;top:645.00px" class="cls_004"><span class="cls_004">circle where it should be displayed. We then offset that value using the value of the</span></div>
<div style="position:absolute;left:5.00px;top:663.00px" class="cls_004"><span class="cls_004">element's </span><span class="cls_007">DesiredSize</span><span class="cls_004"> property, so that the bounding box of each item is centered on that</span></div>
<div style="position:absolute;left:5.00px;top:681.00px" class="cls_004"><span class="cls_004">point.</span></div>
<div style="position:absolute;left:5.00px;top:699.00px" class="cls_004"><span class="cls_004">We then create the element's bounding box using a </span><span class="cls_007">Rect</span><span class="cls_004"> element, with the offset point and</span></div>
<div style="position:absolute;left:5.00px;top:717.00px" class="cls_004"><span class="cls_004">the element's </span><span class="cls_007">DesiredSize</span><span class="cls_004"> property, and pass that to its </span><span class="cls_007">Arrange</span><span class="cls_004"> method to render it. After</span></div>
<div style="position:absolute;left:5.00px;top:735.00px" class="cls_004"><span class="cls_004">each element is rendered, the current angle is changed for the next item. Remember that</span></div>
<div style="position:absolute;left:5.00px;top:753.00px" class="cls_004"><span class="cls_004">we can utilize this panel by setting the </span><span class="cls_007">ItemsPanel</span><span class="cls_004"> property of an </span><span class="cls_007">ItemsControl</span><span class="cls_004"> or one of its</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:146766px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background185.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">derived classes.</span></div>
<div style="position:absolute;left:52.98px;top:27.00px" class="cls_007"><span class="cls_007"><ItemsControl ItemsSource="{Binding Hours}"</span></div>
<div style="position:absolute;left:52.98px;top:40.50px" class="cls_007"><span class="cls_007">TextElement.FontSize="24"></span></div>
<div style="position:absolute;left:67.97px;top:54.00px" class="cls_007"><span class="cls_007"><ItemsControl.ItemsPanel></span></div>
<div style="position:absolute;left:82.97px;top:67.50px" class="cls_007"><span class="cls_007"><ItemsPanelTemplate></span></div>
<div style="position:absolute;left:97.96px;top:81.00px" class="cls_007"><span class="cls_007"><Panels:CircumferencePanel Padding="15" /></span></div>
<div style="position:absolute;left:82.97px;top:94.50px" class="cls_007"><span class="cls_007"></ItemsPanelTemplate></span></div>
<div style="position:absolute;left:67.97px;top:108.00px" class="cls_007"><span class="cls_007"></ItemsControl.ItemsPanel></span></div>
<div style="position:absolute;left:52.98px;top:121.50px" class="cls_007"><span class="cls_007"></ItemsControl></span></div>
<div style="position:absolute;left:5.00px;top:141.75px" class="cls_004"><span class="cls_004">Given some suitable data, we could use this panel to display the numbers on a clock</span></div>
<div style="position:absolute;left:5.00px;top:159.75px" class="cls_004"><span class="cls_004">control, for example. Let's see the </span><span class="cls_007">Hours</span><span class="cls_004"> property that the </span><span class="cls_007">ItemsSource</span><span class="cls_004"> property of our</span></div>
<div style="position:absolute;left:5.00px;top:177.75px" class="cls_004"><span class="cls_004">example </span><span class="cls_007">ItemsControl</span><span class="cls_004"> is data bound to.</span></div>
<div style="position:absolute;left:52.98px;top:201.00px" class="cls_007"><span class="cls_007">private List<int> hours = new List<int>() { 12 };</span></div>
<div style="position:absolute;left:52.98px;top:228.00px" class="cls_007"><span class="cls_007">public List<int> Hours</span></div>
<div style="position:absolute;left:52.98px;top:241.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:255.00px" class="cls_007"><span class="cls_007">get { return hours; }</span></div>
<div style="position:absolute;left:67.97px;top:268.50px" class="cls_007"><span class="cls_007">set { hours = value; NotifyPropertyChanged(); }</span></div>
<div style="position:absolute;left:52.98px;top:282.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:336.00px" class="cls_007"><span class="cls_007">hours.AddRange(Enumerable.Range(1, 11));</span></div>
<div style="position:absolute;left:5.00px;top:356.25px" class="cls_004"><span class="cls_004">As the hour numerals must start with twelve and then go back to one, we declare the</span></div>
<div style="position:absolute;left:5.00px;top:374.25px" class="cls_004"><span class="cls_004">collection with the twelve element initially. At some later stage, possibly during construction,</span></div>
<div style="position:absolute;left:5.00px;top:392.25px" class="cls_004"><span class="cls_004">we then add the remaining numbers to the collection and this is what it looks like when using</span></div>
<div style="position:absolute;left:5.00px;top:410.25px" class="cls_004"><span class="cls_004">our new panel.</span></div>
<div style="position:absolute;left:5.00px;top:648.75px" class="cls_004"><span class="cls_004">This concludes our coverage of the main panels that are available in WPF. While we don't</span></div>
<div style="position:absolute;left:5.00px;top:666.75px" class="cls_004"><span class="cls_004">have the space to have an in-depth look at every other WPF control, we'll find tips and</span></div>
<div style="position:absolute;left:5.00px;top:684.75px" class="cls_004"><span class="cls_004">tricks for a number of them throughout this book. Instead, let's now focus on a few</span></div>
<div style="position:absolute;left:5.00px;top:702.75px" class="cls_004"><span class="cls_004">essential controls and what they can do for us.</span></div>
<div style="position:absolute;left:5.00px;top:720.01px" class="cls_011"><span class="cls_011">Content controls</span></div>
<div style="position:absolute;left:5.00px;top:750.00px" class="cls_004"><span class="cls_004">While this control is not often used directly, one use for it is to render a single data item</span></div>
<div style="position:absolute;left:5.00px;top:768.00px" class="cls_004"><span class="cls_004">according to a particular template. In fact, we often use a </span><span class="cls_007">ContentControl</span><span class="cls_004"> to display our</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:147568px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background186.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">View Models and use a </span><span class="cls_007">DataTemplate</span><span class="cls_004"> object that renders the associated View. We might</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">use some form of </span><span class="cls_007">ItemsControl</span><span class="cls_004"> to display a group of items and a </span><span class="cls_007">ContentControl</span><span class="cls_004"> to</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">display the selected item.</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">As we found out earlier, when looking at the inheritance hierarchy of the </span><span class="cls_007">Button</span><span class="cls_004"> control, the</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_007"><span class="cls_007">ContentControl</span><span class="cls_004"> class extends the </span><span class="cls_007">Control</span><span class="cls_004"> class and adds the ability for derived classes to</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">contain any single CLR object. Note that if we need to specify more than a single object of</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">content, we can use a single panel object that contains further objects.</span></div>
<div style="position:absolute;left:52.98px;top:135.00px" class="cls_007"><span class="cls_007"><Button Width="80" Height="30" TextElement.FontSize="14"></span></div>
<div style="position:absolute;left:67.97px;top:148.50px" class="cls_007"><span class="cls_007"><StackPanel Orientation="Horizontal"></span></div>
<div style="position:absolute;left:82.97px;top:162.00px" class="cls_007"><span class="cls_007"><Rectangle Fill="Cyan" Stroke="Black" StrokeThickness="1"</span></div>
<div style="position:absolute;left:52.98px;top:175.50px" class="cls_007"><span class="cls_007">Width="16"</span></div>
<div style="position:absolute;left:97.96px;top:189.00px" class="cls_007"><span class="cls_007">Height="16" /></span></div>
<div style="position:absolute;left:82.97px;top:202.50px" class="cls_007"><span class="cls_007"><TextBlock Text="Cyan" Margin="5,0,0,0" /></span></div>
<div style="position:absolute;left:67.97px;top:216.00px" class="cls_007"><span class="cls_007"></StackPanel></span></div>
<div style="position:absolute;left:52.98px;top:229.50px" class="cls_007"><span class="cls_007"></Button></span></div>
<div style="position:absolute;left:5.00px;top:318.75px" class="cls_004"><span class="cls_004">We can specify this content through the use of the </span><span class="cls_007">Content</span><span class="cls_004"> property. However, the</span></div>
<div style="position:absolute;left:5.00px;top:336.75px" class="cls_007"><span class="cls_007">ContentControl</span><span class="cls_004"> class specifies the </span><span class="cls_007">Content</span><span class="cls_004"> property in a </span><span class="cls_007">ContentPropertyAttribute</span></div>
<div style="position:absolute;left:5.00px;top:354.75px" class="cls_004"><span class="cls_004">attribute in its class definition and this enables us to set the content by simply adding a child</span></div>
<div style="position:absolute;left:5.00px;top:372.75px" class="cls_004"><span class="cls_004">element to the control. This attribute is used by the XAML processor when it processes</span></div>
<div style="position:absolute;left:5.00px;top:390.75px" class="cls_004"><span class="cls_004">XAML child elements.</span></div>
<div style="position:absolute;left:5.00px;top:408.75px" class="cls_004"><span class="cls_004">If the content is of type </span><span class="cls_007">string</span><span class="cls_004">, then we can use the </span><span class="cls_007">ContentStringFormat</span><span class="cls_004"> property to</span></div>
<div style="position:absolute;left:5.00px;top:426.75px" class="cls_004"><span class="cls_004">specify a particular format for it. Otherwise, we can use the </span><span class="cls_007">ContentTemplate</span><span class="cls_004"> property to</span></div>
<div style="position:absolute;left:5.00px;top:444.75px" class="cls_004"><span class="cls_004">specify a </span><span class="cls_007">DataTemplate</span><span class="cls_004"> to use while rendering the content. Alternatively, the</span></div>
<div style="position:absolute;left:5.00px;top:462.75px" class="cls_007"><span class="cls_007">ContentTemplateSelector</span><span class="cls_004"> property is of type </span><span class="cls_007">DataTemplateSelector</span><span class="cls_004"> and also enables us</span></div>
<div style="position:absolute;left:5.00px;top:480.75px" class="cls_004"><span class="cls_004">to select a </span><span class="cls_007">DataTemplate</span><span class="cls_004">, but based upon some custom condition that we may have. All</span></div>
<div style="position:absolute;left:5.00px;top:498.75px" class="cls_004"><span class="cls_004">derived classes have access to these properties in order to shape the output of their</span></div>
<div style="position:absolute;left:5.00px;top:516.75px" class="cls_004"><span class="cls_004">content.</span></div>
<div style="position:absolute;left:5.00px;top:534.75px" class="cls_004"><span class="cls_004">However, this control is also able to display many primitive types without us having to</span></div>
<div style="position:absolute;left:5.00px;top:552.75px" class="cls_004"><span class="cls_004">specify a custom template. Let's move on to the next section now, where we'll find out</span></div>
<div style="position:absolute;left:5.00px;top:570.75px" class="cls_004"><span class="cls_004">exactly how it manages to accomplish this.</span></div>
<div style="position:absolute;left:5.00px;top:588.00px" class="cls_013"><span class="cls_013">Presenting content</span></div>
<div style="position:absolute;left:5.00px;top:613.50px" class="cls_004"><span class="cls_004">In WPF, there is a special element that is essential, but often little understood. The</span></div>
<div style="position:absolute;left:5.00px;top:631.50px" class="cls_007"><span class="cls_007">ContentPresenter</span><span class="cls_004"> class basically presents content, as its name suggests. It is actually</span></div>
<div style="position:absolute;left:5.00px;top:649.50px" class="cls_004"><span class="cls_004">internally used within </span><span class="cls_007">ContentControl</span><span class="cls_004"> objects to present their content.</span></div>
<div style="position:absolute;left:5.00px;top:667.50px" class="cls_004"><span class="cls_004">That is its sole job and it should not be used for other purposes. The only time that we</span></div>
<div style="position:absolute;left:5.00px;top:685.50px" class="cls_004"><span class="cls_004">should declare these elements is within a </span><span class="cls_007">ControlTemplate</span><span class="cls_004"> of a </span><span class="cls_007">ContentControl</span><span class="cls_004">, or one of</span></div>
<div style="position:absolute;left:5.00px;top:703.50px" class="cls_004"><span class="cls_004">its many derived classes. In these cases, we declare them where we want the actual</span></div>
<div style="position:absolute;left:5.00px;top:721.50px" class="cls_004"><span class="cls_004">content to appear.</span></div>
<div style="position:absolute;left:5.00px;top:739.50px" class="cls_004"><span class="cls_004">Note that specifying the </span><span class="cls_007">TargetType</span><span class="cls_004"> property on a </span><span class="cls_007">ControlTemplate</span><span class="cls_004"> when using a</span></div>
<div style="position:absolute;left:5.00px;top:757.50px" class="cls_007"><span class="cls_007">ContentPresenter</span><span class="cls_004"> will result in its </span><span class="cls_007">Content</span><span class="cls_004"> property being implicitly data bound to the</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:148370px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background187.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_007"><span class="cls_007">Content</span><span class="cls_004"> property of the relevant </span><span class="cls_007">ContentControl</span><span class="cls_004"> element. We are however, free to data</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">bind it explicitly to whatever we like.</span></div>
<div style="position:absolute;left:52.98px;top:45.00px" class="cls_007"><span class="cls_007"><ControlTemplate x:Key="ButtonTemplate" TargetType="{x:Type</span></div>
<div style="position:absolute;left:52.98px;top:58.50px" class="cls_007"><span class="cls_007">Button}"></span></div>
<div style="position:absolute;left:67.97px;top:72.00px" class="cls_007"><span class="cls_007"><ContentPresenter Content="{TemplateBinding ToolTip}" /></span></div>
<div style="position:absolute;left:52.98px;top:85.50px" class="cls_007"><span class="cls_007"></ControlTemplate></span></div>
<div style="position:absolute;left:5.00px;top:105.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">ContentTemplate</span><span class="cls_004"> and </span><span class="cls_007">ContentTemplateSelector</span><span class="cls_004"> properties both mirror those of the</span></div>
<div style="position:absolute;left:5.00px;top:123.75px" class="cls_007"><span class="cls_007">ContentControl</span><span class="cls_004"> class and also enable us to select a </span><span class="cls_007">DataTemplate</span><span class="cls_004"> based upon a custom</span></div>
<div style="position:absolute;left:5.00px;top:141.75px" class="cls_004"><span class="cls_004">condition. Like the </span><span class="cls_007">Content</span><span class="cls_004"> property, both of these properties will also be implicitly data</span></div>
<div style="position:absolute;left:5.00px;top:159.75px" class="cls_004"><span class="cls_004">bound to the properties of the same names in the templated parent if the </span><span class="cls_007">TargetType</span></div>
<div style="position:absolute;left:5.00px;top:177.75px" class="cls_004"><span class="cls_004">property of the </span><span class="cls_007">ControlTemplate</span><span class="cls_004"> has been set.</span></div>
<div style="position:absolute;left:5.00px;top:195.75px" class="cls_004"><span class="cls_004">This usually saves us from having to explicitly data bind these properties, although there are</span></div>
<div style="position:absolute;left:5.00px;top:213.75px" class="cls_004"><span class="cls_004">a few controls where the names of the relevant properties do not match up. In these cases,</span></div>
<div style="position:absolute;left:5.00px;top:231.75px" class="cls_004"><span class="cls_004">we can use the </span><span class="cls_007">ContentSource</span><span class="cls_004"> property as a shortcut to data bind the </span><span class="cls_007">Content</span><span class="cls_004">,</span></div>
<div style="position:absolute;left:5.00px;top:249.75px" class="cls_007"><span class="cls_007">ContentTemplate</span><span class="cls_004"> and </span><span class="cls_007">ContentTemplateSelector</span><span class="cls_004"> properties.</span></div>
<div style="position:absolute;left:5.00px;top:267.75px" class="cls_004"><span class="cls_004">If we set this property to </span><span class="cls_007">Header</span><span class="cls_004"> for example, the Framework will look for a property named</span></div>
<div style="position:absolute;left:5.00px;top:285.75px" class="cls_007"><span class="cls_007">Header </span><span class="cls_004">on the </span><span class="cls_007">ContentControl</span><span class="cls_004"> object to implicitly data bind to the </span><span class="cls_007">Content</span><span class="cls_004"> property of the</span></div>
<div style="position:absolute;left:5.00px;top:303.75px" class="cls_004"><span class="cls_004">presenter. Likewise, it will look for properties named </span><span class="cls_007">HeaderTemplate</span><span class="cls_004"> and</span></div>
<div style="position:absolute;left:5.00px;top:321.75px" class="cls_007"><span class="cls_007">HeaderTemplateSelector</span><span class="cls_004"> to implicitly data bind to the </span><span class="cls_007">ContentTemplate</span><span class="cls_004"> and</span></div>
<div style="position:absolute;left:5.00px;top:339.75px" class="cls_007"><span class="cls_007">ContentTemplateSelector</span><span class="cls_004"> properties.</span></div>
<div style="position:absolute;left:5.00px;top:357.75px" class="cls_004"><span class="cls_004">This is primarily used in a </span><span class="cls_007">ControlTemplate</span><span class="cls_004"> for a </span><span class="cls_007">HeaderedContentControl</span><span class="cls_004"> element, or one</span></div>
<div style="position:absolute;left:5.00px;top:375.75px" class="cls_004"><span class="cls_004">of its derived classes.</span></div>
<div style="position:absolute;left:52.98px;top:399.00px" class="cls_007"><span class="cls_007"><ControlTemplate x:Key="TabItemTemplate" TargetType="{x:Type</span></div>
<div style="position:absolute;left:52.98px;top:412.50px" class="cls_007"><span class="cls_007">TabItem}"></span></div>
<div style="position:absolute;left:67.97px;top:426.00px" class="cls_007"><span class="cls_007"><StackPanel></span></div>
<div style="position:absolute;left:82.97px;top:439.50px" class="cls_007"><span class="cls_007"><ContentPresenter ContentSource="Header" /></span></div>
<div style="position:absolute;left:82.97px;top:453.00px" class="cls_007"><span class="cls_007"><ContentPresenter ContentSource="Content" /></span></div>
<div style="position:absolute;left:67.97px;top:466.50px" class="cls_007"><span class="cls_007"></StackPanel></span></div>
<div style="position:absolute;left:52.98px;top:480.00px" class="cls_007"><span class="cls_007"></ControlTemplate></span></div>
<div style="position:absolute;left:5.00px;top:500.25px" class="cls_004"><span class="cls_004">There are specific rules that determine what the </span><span class="cls_007">ContentPresenter</span><span class="cls_004"> will display. If the</span></div>
<div style="position:absolute;left:5.00px;top:518.25px" class="cls_007"><span class="cls_007">ContentTemplate</span><span class="cls_004"> or </span><span class="cls_007">ContentTemplateSelector</span><span class="cls_004"> property is set, then the data object</span></div>
<div style="position:absolute;left:5.00px;top:536.25px" class="cls_004"><span class="cls_004">specified by the </span><span class="cls_007">Content</span><span class="cls_004"> property will have the resulting data template applied to it.</span></div>
<div style="position:absolute;left:5.00px;top:554.25px" class="cls_004"><span class="cls_004">Likewise, if a data template of the relevant type is found within scope of the</span></div>
<div style="position:absolute;left:5.00px;top:572.25px" class="cls_007"><span class="cls_007">ContentPresenter</span><span class="cls_004"> element, it will be applied.</span></div>
<div style="position:absolute;left:5.00px;top:590.25px" class="cls_004"><span class="cls_004">If the content object is a UI element, or one is returned from a type converter, then the</span></div>
<div style="position:absolute;left:5.00px;top:608.25px" class="cls_004"><span class="cls_004">element is displayed directly. If the object is a string, or a string is returned from a type</span></div>
<div style="position:absolute;left:5.00px;top:626.25px" class="cls_004"><span class="cls_004">converter, then it will be set as the </span><span class="cls_007">Text</span><span class="cls_004"> property of a </span><span class="cls_007">TextBlock</span><span class="cls_004"> control and that will be</span></div>
<div style="position:absolute;left:5.00px;top:644.25px" class="cls_004"><span class="cls_004">displayed. Likewise, all other objects simply have the </span><span class="cls_007">ToString</span><span class="cls_004"> method called on them and</span></div>
<div style="position:absolute;left:5.00px;top:662.25px" class="cls_004"><span class="cls_004">this output is rendered in a </span><span class="cls_007">TextBlock</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:679.51px" class="cls_011"><span class="cls_011">Items controls</span></div>
<div style="position:absolute;left:5.00px;top:709.50px" class="cls_004"><span class="cls_004">We've already seen a fair number of examples of the </span><span class="cls_007">ItemsControl</span><span class="cls_004"> class, but we'll now</span></div>
<div style="position:absolute;left:5.00px;top:727.50px" class="cls_004"><span class="cls_004">take a closer look at this control. In the simplest terms, an </span><span class="cls_007">ItemsControl</span><span class="cls_004"> contains a variable</span></div>
<div style="position:absolute;left:5.00px;top:745.50px" class="cls_004"><span class="cls_004">number of </span><span class="cls_007">ContentPresenter</span><span class="cls_004"> elements and enables us to display a collection of items. It is</span></div>
<div style="position:absolute;left:5.00px;top:763.50px" class="cls_004"><span class="cls_004">the base class for most common collection controls, such as the </span><span class="cls_007">ListBox</span><span class="cls_004">, </span><span class="cls_007">ComboBox</span><span class="cls_004"> and</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:149172px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background188.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_007"><span class="cls_007">TreeView</span><span class="cls_004"> controls.</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">Each of these derived classes adds a specific look and set of capabilities, such as a border</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">and the notion of a selected item. If we do not require these additional features and simply</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">want to display a number of items, then we should just use the </span><span class="cls_007">ItemsControl</span><span class="cls_004">, because it is</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">more efficient than its derived classes.</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">When using MVVM, we typically data bind a collection that implements the </span><span class="cls_007">IEnumerable</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">interface from our View Model to the </span><span class="cls_007">ItemsControl.ItemsSource</span><span class="cls_004"> property. However, there</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">is also an </span><span class="cls_007">Items</span><span class="cls_004"> property that will reflect the items in the data bound collection.</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">To clarify this further, either property can be used to populate the collection of items to</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">display. However, only one can be used at a time, so if you have data bound a collection to</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">ItemsSource</span><span class="cls_004"> property, then you cannot add items using the </span><span class="cls_007">Items</span><span class="cls_004"> property. In this case,</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">Items</span><span class="cls_004"> collection will become read-only.</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">If we need to display a collection of items that does not implement the </span><span class="cls_007">IEnumerable</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">interface, then we will need to add them using the </span><span class="cls_007">Items</span><span class="cls_004"> property. Note that the </span><span class="cls_007">Items</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">property is implicitly used when items are declared as the content of an </span><span class="cls_007">ItemsControl</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">element in XAML. However, when using MVVM, we generally use the </span><span class="cls_007">ItemsSource</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">property.</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">When displaying items in an </span><span class="cls_007">ItemsControl</span><span class="cls_004">¸ each item in the collection will implicitly be</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_004"><span class="cls_004">wrapped in a </span><span class="cls_007">ContentPresenter</span><span class="cls_004"> container element. The type of this container element will</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_004"><span class="cls_004">depend upon the type of collection control used. For example, a </span><span class="cls_007">ComboBox</span><span class="cls_004"> would wrap its</span></div>
<div style="position:absolute;left:5.00px;top:363.75px" class="cls_004"><span class="cls_004">items in </span><span class="cls_007">ComboBoxItem</span><span class="cls_004"> elements.</span></div>
<div style="position:absolute;left:5.00px;top:381.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">ItemContainerStyle</span><span class="cls_004"> and </span><span class="cls_007">ItemContainerStyleSelector</span><span class="cls_004"> properties enable us to provide</span></div>
<div style="position:absolute;left:5.00px;top:399.75px" class="cls_004"><span class="cls_004">a style for these container items. We must ensure that the styles that we provide are</span></div>
<div style="position:absolute;left:5.00px;top:417.75px" class="cls_004"><span class="cls_004">targeted to the correct type of container control. For example, if we were using a </span><span class="cls_007">ListBox</span><span class="cls_004">,</span></div>
<div style="position:absolute;left:5.00px;top:435.75px" class="cls_004"><span class="cls_004">then we would need to provide a style targeting the </span><span class="cls_007">ListBoxItem</span><span class="cls_004"> type, as in the following</span></div>
<div style="position:absolute;left:5.00px;top:453.75px" class="cls_004"><span class="cls_004">example.</span></div>
<div style="position:absolute;left:5.00px;top:471.75px" class="cls_004"><span class="cls_004">Note that we can explicitly declare these container items, although there is little point in</span></div>
<div style="position:absolute;left:5.00px;top:489.75px" class="cls_004"><span class="cls_004">doing so, as it will otherwise be done for us. Furthermore, when using MVVM, we do not</span></div>
<div style="position:absolute;left:5.00px;top:507.75px" class="cls_004"><span class="cls_004">typically work with UI elements, preferring to work with data objects in the View Models</span></div>
<div style="position:absolute;left:5.00px;top:525.75px" class="cls_004"><span class="cls_004">and data bind to the </span><span class="cls_007">ItemsSource</span><span class="cls_004"> property instead.</span></div>
<div style="position:absolute;left:5.00px;top:543.75px" class="cls_004"><span class="cls_004">As we have already seen, the </span><span class="cls_007">ItemsControl</span><span class="cls_004"> class has an </span><span class="cls_007">ItemsPanel</span><span class="cls_004"> property of type</span></div>
<div style="position:absolute;left:5.00px;top:561.75px" class="cls_007"><span class="cls_007">ItemsPanelTemplate</span><span class="cls_004">, that enables us to change the type of panel that the collection control</span></div>
<div style="position:absolute;left:5.00px;top:579.75px" class="cls_004"><span class="cls_004">uses to layout its items. When we want to customize the template of an </span><span class="cls_007">ItemsControl</span><span class="cls_004">, we</span></div>
<div style="position:absolute;left:5.00px;top:597.75px" class="cls_004"><span class="cls_004">have two choices regarding how we render the control's child items.</span></div>
<div style="position:absolute;left:52.98px;top:621.00px" class="cls_007"><span class="cls_007"><ControlTemplate x:Key="Template1" TargetType="{x:Type</span></div>
<div style="position:absolute;left:52.98px;top:634.50px" class="cls_007"><span class="cls_007">ItemsControl}"></span></div>
<div style="position:absolute;left:67.97px;top:648.00px" class="cls_007"><span class="cls_007"><StackPanel Orientation="Horizontal" IsItemsHost="True" /></span></div>
<div style="position:absolute;left:52.98px;top:661.50px" class="cls_007"><span class="cls_007"></ControlTemplate></span></div>
<div style="position:absolute;left:5.00px;top:681.75px" class="cls_004"><span class="cls_004">We already saw an example of the preceding method in the previous section. In this way,</span></div>
<div style="position:absolute;left:5.00px;top:699.75px" class="cls_004"><span class="cls_004">we specify the actual items panel itself and set the </span><span class="cls_007">IsItemsHost</span><span class="cls_004"> property to </span><span class="cls_007">true</span><span class="cls_004"> on it to</span></div>
<div style="position:absolute;left:5.00px;top:717.75px" class="cls_004"><span class="cls_004">indicate that it is indeed to be used as the control's items panel. Using the alternative</span></div>
<div style="position:absolute;left:5.00px;top:735.75px" class="cls_004"><span class="cls_004">method, we need to declare an </span><span class="cls_007">ItemsPresenter</span><span class="cls_004"> element, which specifies where the actual</span></div>
<div style="position:absolute;left:5.00px;top:753.75px" class="cls_004"><span class="cls_004">items panel will be rendered. Note that this element will be replaced by the actual items</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:149974px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background189.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">panel being used at runtime.</span></div>
<div style="position:absolute;left:52.98px;top:27.00px" class="cls_007"><span class="cls_007"><ControlTemplate x:Key="Template2" TargetType="{x:Type</span></div>
<div style="position:absolute;left:52.98px;top:40.50px" class="cls_007"><span class="cls_007">ItemsControl}"></span></div>
<div style="position:absolute;left:67.97px;top:54.00px" class="cls_007"><span class="cls_007"><ItemsPresenter /></span></div>
<div style="position:absolute;left:52.98px;top:67.50px" class="cls_007"><span class="cls_007"></ControlTemplate></span></div>
<div style="position:absolute;left:5.00px;top:87.75px" class="cls_004"><span class="cls_004">As with the </span><span class="cls_007">ContentControl</span><span class="cls_004"> class, the </span><span class="cls_007">ItemsControl</span><span class="cls_004"> class also provides properties that</span></div>
<div style="position:absolute;left:5.00px;top:105.75px" class="cls_004"><span class="cls_004">enable us to shape its data items. The </span><span class="cls_007">ItemTemplate</span><span class="cls_004"> and </span><span class="cls_007">ItemTemplateSelector</span><span class="cls_004"> properties</span></div>
<div style="position:absolute;left:5.00px;top:123.75px" class="cls_004"><span class="cls_004">let us apply a data template for the items. However, if we just need a simple textual output,</span></div>
<div style="position:absolute;left:5.00px;top:141.75px" class="cls_004"><span class="cls_004">we can use the </span><span class="cls_007">DisplayMemberPath</span><span class="cls_004"> property to specify the name of the property from the</span></div>
<div style="position:absolute;left:5.00px;top:159.75px" class="cls_004"><span class="cls_004">object to display and avoid defining a data template at all. Alternatively, we can set the</span></div>
<div style="position:absolute;left:5.00px;top:177.75px" class="cls_007"><span class="cls_007">ItemStringFormat</span><span class="cls_004"> property to format the output as a string.</span></div>
<div style="position:absolute;left:5.00px;top:195.75px" class="cls_004"><span class="cls_004">Another interesting property is the </span><span class="cls_007">AlternationCount</span><span class="cls_004"> property, which enables us to style</span></div>
<div style="position:absolute;left:5.00px;top:213.75px" class="cls_004"><span class="cls_004">alternating containers differently. We can set it to any number and the alternating sequence</span></div>
<div style="position:absolute;left:5.00px;top:231.75px" class="cls_004"><span class="cls_004">will repeat after that many items have been rendered. As a simple example, let's use a</span></div>
<div style="position:absolute;left:5.00px;top:249.75px" class="cls_007"><span class="cls_007">ListBox</span><span class="cls_004">, because the </span><span class="cls_007">ListBoxItem</span><span class="cls_004"> controls that will be wrapped around our items have</span></div>
<div style="position:absolute;left:5.00px;top:267.75px" class="cls_004"><span class="cls_004">appearance properties that we can alternate.</span></div>
<div style="position:absolute;left:52.98px;top:291.00px" class="cls_007"><span class="cls_007"><ListBox ItemsSource="{Binding Users}" AlternationCount="3"></span></div>
<div style="position:absolute;left:67.97px;top:304.50px" class="cls_007"><span class="cls_007"><ListBox.ItemContainerStyle></span></div>
<div style="position:absolute;left:82.97px;top:318.00px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type ListBoxItem}"></span></div>
<div style="position:absolute;left:97.96px;top:331.50px" class="cls_007"><span class="cls_007"><Setter Property="FontSize" Value="14" /></span></div>
<div style="position:absolute;left:97.96px;top:345.00px" class="cls_007"><span class="cls_007"><Setter Property="Foreground" Value="White" /></span></div>
<div style="position:absolute;left:97.96px;top:358.50px" class="cls_007"><span class="cls_007"><Setter Property="Padding" Value="5" /></span></div>
<div style="position:absolute;left:97.96px;top:372.00px" class="cls_007"><span class="cls_007"><Style.Triggers></span></div>
<div style="position:absolute;left:112.96px;top:385.50px" class="cls_007"><span class="cls_007"><Trigger Property="ListBox.AlternationIndex" Value="0"></span></div>
<div style="position:absolute;left:127.95px;top:399.00px" class="cls_007"><span class="cls_007"><Setter Property="Background" Value="Red" /></span></div>
<div style="position:absolute;left:112.96px;top:412.50px" class="cls_007"><span class="cls_007"></Trigger></span></div>
<div style="position:absolute;left:112.96px;top:426.00px" class="cls_007"><span class="cls_007"><Trigger Property="ListBox.AlternationIndex" Value="1"></span></div>
<div style="position:absolute;left:127.95px;top:439.50px" class="cls_007"><span class="cls_007"><Setter Property="Background" Value="Green" /></span></div>
<div style="position:absolute;left:112.96px;top:453.00px" class="cls_007"><span class="cls_007"></Trigger></span></div>
<div style="position:absolute;left:112.96px;top:466.50px" class="cls_007"><span class="cls_007"><Trigger Property="ListBox.AlternationIndex" Value="2"></span></div>
<div style="position:absolute;left:127.95px;top:480.00px" class="cls_007"><span class="cls_007"><Setter Property="Background" Value="Blue" /></span></div>
<div style="position:absolute;left:112.96px;top:493.50px" class="cls_007"><span class="cls_007"></Trigger></span></div>
<div style="position:absolute;left:97.96px;top:507.00px" class="cls_007"><span class="cls_007"></Style.Triggers></span></div>
<div style="position:absolute;left:82.97px;top:520.50px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:67.97px;top:534.00px" class="cls_007"><span class="cls_007"></ListBox.ItemContainerStyle></span></div>
<div style="position:absolute;left:52.98px;top:547.50px" class="cls_007"><span class="cls_007"></ListBox></span></div>
<div style="position:absolute;left:5.00px;top:567.75px" class="cls_004"><span class="cls_004">Here, we set the </span><span class="cls_007">AlternationCount</span><span class="cls_004"> property to </span><span class="cls_007">3</span><span class="cls_004">, so we can have three different styles for</span></div>
<div style="position:absolute;left:5.00px;top:585.75px" class="cls_004"><span class="cls_004">our items and this pattern will be repeated for every three further items. We make a style</span></div>
<div style="position:absolute;left:5.00px;top:603.75px" class="cls_004"><span class="cls_004">for the item containers using the </span><span class="cls_007">ItemContainerStyle</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:5.00px;top:621.75px" class="cls_004"><span class="cls_004">In this style, we use some simple triggers to change the color of the container background,</span></div>
<div style="position:absolute;left:5.00px;top:639.75px" class="cls_004"><span class="cls_004">depending on the value of the </span><span class="cls_007">AlternationIndex</span><span class="cls_004"> property. Notice that the</span></div>
<div style="position:absolute;left:5.00px;top:657.75px" class="cls_007"><span class="cls_007">AlternationCount</span><span class="cls_004"> property starts at </span><span class="cls_007">0</span><span class="cls_004">, so the first item will have a red background, the</span></div>
<div style="position:absolute;left:5.00px;top:675.75px" class="cls_004"><span class="cls_004">second will have green, the third will have blue, then the pattern will repeat and the fourth</span></div>
<div style="position:absolute;left:5.00px;top:693.75px" class="cls_004"><span class="cls_004">will have red and so on.</span></div>
<div style="position:absolute;left:5.00px;top:711.75px" class="cls_004"><span class="cls_004">Alternatively, we could have declared an </span><span class="cls_007">AlternationConverter</span><span class="cls_004"> instance for each property</span></div>
<div style="position:absolute;left:5.00px;top:729.75px" class="cls_004"><span class="cls_004">that we wanted to alter and data bind them to the </span><span class="cls_007">AlternationIndex</span><span class="cls_004"> property and the</span></div>
<div style="position:absolute;left:5.00px;top:747.75px" class="cls_004"><span class="cls_004">converter. We could create the same visual output using this XAML instead.</span></div>
<div style="position:absolute;left:52.98px;top:771.00px" class="cls_007"><span class="cls_007"><ListBox ItemsSource="{Binding Users}" AlternationCount="3"></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:150776px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background190.jpg" width=612 height=792></div>
<div style="position:absolute;left:67.97px;top:3.00px" class="cls_007"><span class="cls_007"><ListBox.Resources></span></div>
<div style="position:absolute;left:82.97px;top:16.50px" class="cls_007"><span class="cls_007"><AlternationConverter x:Key="BackgroundConverter"></span></div>
<div style="position:absolute;left:97.96px;top:30.00px" class="cls_007"><span class="cls_007"><SolidColorBrush>Red</SolidColorBrush></span></div>
<div style="position:absolute;left:97.96px;top:43.50px" class="cls_007"><span class="cls_007"><SolidColorBrush>Green</SolidColorBrush></span></div>
<div style="position:absolute;left:97.96px;top:57.00px" class="cls_007"><span class="cls_007"><SolidColorBrush>Blue</SolidColorBrush></span></div>
<div style="position:absolute;left:82.97px;top:70.50px" class="cls_007"><span class="cls_007"></AlternationConverter></span></div>
<div style="position:absolute;left:67.97px;top:84.00px" class="cls_007"><span class="cls_007"></ListBox.Resources></span></div>
<div style="position:absolute;left:67.97px;top:97.50px" class="cls_007"><span class="cls_007"><ListBox.ItemContainerStyle></span></div>
<div style="position:absolute;left:82.97px;top:111.00px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type ListBoxItem}"></span></div>
<div style="position:absolute;left:97.96px;top:124.50px" class="cls_007"><span class="cls_007"><Setter Property="FontSize" Value="14" /></span></div>
<div style="position:absolute;left:97.96px;top:138.00px" class="cls_007"><span class="cls_007"><Setter Property="Foreground" Value="White" /></span></div>
<div style="position:absolute;left:97.96px;top:151.50px" class="cls_007"><span class="cls_007"><Setter Property="Padding" Value="5" /></span></div>
<div style="position:absolute;left:97.96px;top:165.00px" class="cls_007"><span class="cls_007"><Setter Property="Background"</span></div>
<div style="position:absolute;left:112.96px;top:178.50px" class="cls_007"><span class="cls_007">Value="{Binding(ItemsControl.AlternationIndex),</span></div>
<div style="position:absolute;left:112.96px;top:192.00px" class="cls_007"><span class="cls_007">RelativeSource={RelativeSource Self},</span></div>
<div style="position:absolute;left:112.96px;top:205.50px" class="cls_007"><span class="cls_007">Converter={StaticResource BackgroundConverter}}" /></span></div>
<div style="position:absolute;left:82.97px;top:219.00px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:67.97px;top:232.50px" class="cls_007"><span class="cls_007"></ListBox.ItemContainerStyle></span></div>
<div style="position:absolute;left:52.98px;top:246.00px" class="cls_007"><span class="cls_007"></ListBox></span></div>
<div style="position:absolute;left:5.00px;top:266.25px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">AlternationConverter</span><span class="cls_004"> class works by simply returning the item from its collection that</span></div>
<div style="position:absolute;left:5.00px;top:284.25px" class="cls_004"><span class="cls_004">relates to the specified </span><span class="cls_007">AlternationIndex</span><span class="cls_004"> value, where the first item is returned for index</span></div>
<div style="position:absolute;left:5.00px;top:302.25px" class="cls_004"><span class="cls_004">zero. Note that we need to include the parenthesis around the data bound class and</span></div>
<div style="position:absolute;left:5.00px;top:320.25px" class="cls_004"><span class="cls_004">property name because it is an Attached Property and we need to use a</span></div>
<div style="position:absolute;left:5.00px;top:338.25px" class="cls_007"><span class="cls_007">RelativeSource.Self</span><span class="cls_004"> binding because the property is set on the item container object</span></div>
<div style="position:absolute;left:5.00px;top:356.25px" class="cls_004"><span class="cls_004">itself. Let's see the output of these two code examples.</span></div>
<div style="position:absolute;left:5.00px;top:569.25px" class="cls_004"><span class="cls_004">There is one more useful property that the </span><span class="cls_007">ItemsControl</span><span class="cls_004"> class provides and that is the</span></div>
<div style="position:absolute;left:5.00px;top:587.25px" class="cls_007"><span class="cls_007">GroupStyle</span><span class="cls_004"> property, which is used to display the child items in groups. To group items in</span></div>
<div style="position:absolute;left:5.00px;top:605.25px" class="cls_004"><span class="cls_004">the UI, we need to accomplish a few simple tasks.</span></div>
<div style="position:absolute;left:5.00px;top:623.25px" class="cls_004"><span class="cls_004">We first need to data bind a </span><span class="cls_007">CollectionViewSource</span><span class="cls_004"> with one or more</span></div>
<div style="position:absolute;left:5.00px;top:641.25px" class="cls_007"><span class="cls_007">PropertyGroupDescription</span><span class="cls_004"> elements to our </span><span class="cls_007">Users</span><span class="cls_004"> collection from the last example. We</span></div>
<div style="position:absolute;left:5.00px;top:659.25px" class="cls_004"><span class="cls_004">then need to set that as the </span><span class="cls_007">ItemsSource</span><span class="cls_004"> value for the </span><span class="cls_007">ItemsControl</span><span class="cls_004"> and then set up its</span></div>
<div style="position:absolute;left:5.00px;top:677.25px" class="cls_007"><span class="cls_007">GroupStyle</span><span class="cls_004">. Let's see the </span><span class="cls_007">CollectionViewSource</span><span class="cls_004"> object that we need to declare in the local</span></div>
<div style="position:absolute;left:5.00px;top:695.25px" class="cls_007"><span class="cls_007">Resources</span><span class="cls_004"> section.</span></div>
<div style="position:absolute;left:52.98px;top:718.50px" class="cls_007"><span class="cls_007"><CollectionViewSource x:Key="GroupedUsers" Source="{Binding</span></div>
<div style="position:absolute;left:52.98px;top:732.00px" class="cls_007"><span class="cls_007">Users}"></span></div>
<div style="position:absolute;left:67.97px;top:745.50px" class="cls_007"><span class="cls_007"><CollectionViewSource.GroupDescriptions></span></div>
<div style="position:absolute;left:82.97px;top:759.00px" class="cls_007"><span class="cls_007"><PropertyGroupDescription PropertyName="Name"</span></div>
<div style="position:absolute;left:97.96px;top:772.50px" class="cls_007"><span class="cls_007">Converter="{StaticResource StringToFirstLetterConverter}" /></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:151578px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background191.jpg" width=612 height=792></div>
<div style="position:absolute;left:67.97px;top:3.00px" class="cls_007"><span class="cls_007"></CollectionViewSource.GroupDescriptions></span></div>
<div style="position:absolute;left:52.98px;top:16.50px" class="cls_007"><span class="cls_007"></CollectionViewSource></span></div>
<div style="position:absolute;left:5.00px;top:36.75px" class="cls_004"><span class="cls_004">We specify the property that we want to use to group items by using the </span><span class="cls_007">PropertyName</span></div>
<div style="position:absolute;left:5.00px;top:54.75px" class="cls_004"><span class="cls_004">property of the </span><span class="cls_007">PropertyGroupDescription</span><span class="cls_004"> element. Note that in our case, we only have a</span></div>
<div style="position:absolute;left:5.00px;top:72.75px" class="cls_004"><span class="cls_004">few </span><span class="cls_007">User</span><span class="cls_004"> objects and so, there would be no groups if we simply grouped by name.</span></div>
<div style="position:absolute;left:5.00px;top:90.75px" class="cls_004"><span class="cls_004">Therefore, we added a converter to return the first letter from each name to group on and</span></div>
<div style="position:absolute;left:5.00px;top:108.75px" class="cls_004"><span class="cls_004">specified it using the </span><span class="cls_007">Converter</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:52.98px;top:132.00px" class="cls_007"><span class="cls_007">using System;</span></div>
<div style="position:absolute;left:52.98px;top:145.50px" class="cls_007"><span class="cls_007">using System.Globalization;</span></div>
<div style="position:absolute;left:52.98px;top:159.00px" class="cls_007"><span class="cls_007">using System.Windows;</span></div>
<div style="position:absolute;left:52.98px;top:172.50px" class="cls_007"><span class="cls_007">using System.Windows.Data;</span></div>
<div style="position:absolute;left:52.98px;top:199.50px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.Converters</span></div>
<div style="position:absolute;left:52.98px;top:213.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:226.50px" class="cls_007"><span class="cls_007">[ValueConversion(typeof(string), typeof(string))]</span></div>
<div style="position:absolute;left:67.97px;top:240.00px" class="cls_007"><span class="cls_007">public class StringToFirstLetterConverter : IValueConverter</span></div>
<div style="position:absolute;left:67.97px;top:253.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:267.00px" class="cls_007"><span class="cls_007">public object Convert(object value, Type targetType, object</span></div>
<div style="position:absolute;left:52.98px;top:280.50px" class="cls_007"><span class="cls_007">parameter,</span></div>
<div style="position:absolute;left:97.96px;top:294.00px" class="cls_007"><span class="cls_007">CultureInfo culture)</span></div>
<div style="position:absolute;left:82.97px;top:307.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:321.00px" class="cls_007"><span class="cls_007">if (value == null) return DependencyProperty.UnsetValue;</span></div>
<div style="position:absolute;left:97.96px;top:334.50px" class="cls_007"><span class="cls_007">return value.ToString()[0];</span></div>
<div style="position:absolute;left:82.97px;top:348.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:375.00px" class="cls_007"><span class="cls_007">public object ConvertBack(object value, Type targetType,</span></div>
<div style="position:absolute;left:97.96px;top:388.50px" class="cls_007"><span class="cls_007">object parameter, CultureInfo culture)</span></div>
<div style="position:absolute;left:82.97px;top:402.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:415.50px" class="cls_007"><span class="cls_007">return DependencyProperty.UnsetValue;</span></div>
<div style="position:absolute;left:82.97px;top:429.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:442.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:456.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:476.25px" class="cls_004"><span class="cls_004">In this converter, we specify the data types that are involved in the implementation of the</span></div>
<div style="position:absolute;left:5.00px;top:494.25px" class="cls_004"><span class="cls_004">converter in the </span><span class="cls_007">ValueConversion</span><span class="cls_004"> attribute, even though they are the same type. In the</span></div>
<div style="position:absolute;left:5.00px;top:512.25px" class="cls_007"><span class="cls_007">Convert</span><span class="cls_004"> method, we check the validity of our </span><span class="cls_007">value</span><span class="cls_004"> input parameter and return the</span></div>
<div style="position:absolute;left:5.00px;top:530.25px" class="cls_007"><span class="cls_007">DependencyProperty.UnsetValue</span><span class="cls_004"> value if it is null. For valid values, we simply return the first</span></div>
<div style="position:absolute;left:5.00px;top:548.25px" class="cls_004"><span class="cls_004">letter of their string representations.</span></div>
<div style="position:absolute;left:5.00px;top:566.25px" class="cls_004"><span class="cls_004">As we do not need, or would not be able to convert anything back using this converter, the</span></div>
<div style="position:absolute;left:5.00px;top:584.25px" class="cls_007"><span class="cls_007">ConvertBack</span><span class="cls_004"> method simply returns the </span><span class="cls_007">DependencyProperty.UnsetValue</span><span class="cls_004"> value. By</span></div>
<div style="position:absolute;left:5.00px;top:602.25px" class="cls_004"><span class="cls_004">attaching this converter to the </span><span class="cls_007">PropertyGroupDescription</span><span class="cls_004"> element, we are now able to</span></div>
<div style="position:absolute;left:5.00px;top:620.25px" class="cls_004"><span class="cls_004">group by the first letter of each name. Let's now see how we can declare the </span><span class="cls_007">GroupStyle</span></div>
<div style="position:absolute;left:5.00px;top:638.25px" class="cls_004"><span class="cls_004">object.</span></div>
<div style="position:absolute;left:52.98px;top:661.50px" class="cls_007"><span class="cls_007"><ItemsControl ItemsSource="{Binding Source={StaticResource</span></div>
<div style="position:absolute;left:52.98px;top:675.00px" class="cls_007"><span class="cls_007">GroupedUsers}}"</span></div>
<div style="position:absolute;left:67.97px;top:688.50px" class="cls_007"><span class="cls_007">FontSize="14"></span></div>
<div style="position:absolute;left:67.97px;top:702.00px" class="cls_007"><span class="cls_007"><ItemsControl.GroupStyle></span></div>
<div style="position:absolute;left:82.97px;top:715.50px" class="cls_007"><span class="cls_007"><GroupStyle></span></div>
<div style="position:absolute;left:97.96px;top:729.00px" class="cls_007"><span class="cls_007"><GroupStyle.HeaderTemplate></span></div>
<div style="position:absolute;left:112.96px;top:742.50px" class="cls_007"><span class="cls_007"><DataTemplate></span></div>
<div style="position:absolute;left:127.95px;top:756.00px" class="cls_007"><span class="cls_007"><TextBlock Text="{Binding Name,</span></div>
<div style="position:absolute;left:142.94px;top:769.50px" class="cls_007"><span class="cls_007">Converter={StaticResource</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:152380px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background192.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:3.00px" class="cls_007"><span class="cls_007">StringToFirstLetterConverter}}"</span></div>
<div style="position:absolute;left:142.94px;top:16.50px" class="cls_007"><span class="cls_007">Background="Black" Foreground="White" FontWeight="Bold"</span></div>
<div style="position:absolute;left:142.94px;top:30.00px" class="cls_007"><span class="cls_007">Padding="5,4" /></span></div>
<div style="position:absolute;left:112.96px;top:43.50px" class="cls_007"><span class="cls_007"></DataTemplate></span></div>
<div style="position:absolute;left:97.96px;top:57.00px" class="cls_007"><span class="cls_007"></GroupStyle.HeaderTemplate></span></div>
<div style="position:absolute;left:82.97px;top:70.50px" class="cls_007"><span class="cls_007"></GroupStyle></span></div>
<div style="position:absolute;left:67.97px;top:84.00px" class="cls_007"><span class="cls_007"></ItemsControl.GroupStyle></span></div>
<div style="position:absolute;left:67.97px;top:97.50px" class="cls_007"><span class="cls_007"><ItemsControl.ItemTemplate></span></div>
<div style="position:absolute;left:82.97px;top:111.00px" class="cls_007"><span class="cls_007"><DataTemplate DataType="{x:Type DataModels:User}"></span></div>
<div style="position:absolute;left:90.46px;top:124.50px" class="cls_007"><span class="cls_007"><TextBlock Text="{Binding Name}" Background="White"</span></div>
<div style="position:absolute;left:52.98px;top:138.00px" class="cls_007"><span class="cls_007">Foreground="Black"</span></div>
<div style="position:absolute;left:105.46px;top:151.50px" class="cls_007"><span class="cls_007">Padding="0,2" /></span></div>
<div style="position:absolute;left:82.97px;top:165.00px" class="cls_007"><span class="cls_007"></DataTemplate></span></div>
<div style="position:absolute;left:67.97px;top:178.50px" class="cls_007"><span class="cls_007"></ItemsControl.ItemTemplate></span></div>
<div style="position:absolute;left:52.98px;top:192.00px" class="cls_007"><span class="cls_007"></ItemsControl></span></div>
<div style="position:absolute;left:5.00px;top:225.00px" class="cls_004"><span class="cls_004">Note that we need to use the </span><span class="cls_007">Binding.Source</span><span class="cls_004"> property to access the</span></div>
<div style="position:absolute;left:5.00px;top:243.00px" class="cls_007"><span class="cls_007">CollectionViewSource</span><span class="cls_004"> object named </span><span class="cls_007">GroupedUsers</span><span class="cls_004"> from the local </span><span class="cls_007">Resources</span><span class="cls_004"> section. We</span></div>
<div style="position:absolute;left:5.00px;top:261.00px" class="cls_004"><span class="cls_004">then declare the data template that defines what each group header will look like in the</span></div>
<div style="position:absolute;left:5.00px;top:279.00px" class="cls_007"><span class="cls_007">HeaderTemplate</span><span class="cls_004"> property. Here we make use of the </span><span class="cls_007">StringToFirstLetterConverter</span></div>
<div style="position:absolute;left:5.00px;top:297.00px" class="cls_004"><span class="cls_004">instance that has also been declared in a suitable resource collection, and set a few basic</span></div>
<div style="position:absolute;left:5.00px;top:315.00px" class="cls_004"><span class="cls_004">style properties.</span></div>
<div style="position:absolute;left:5.00px;top:333.00px" class="cls_004"><span class="cls_004">Next, we specify a second data template, but one that defines what each item in each</span></div>
<div style="position:absolute;left:5.00px;top:351.00px" class="cls_004"><span class="cls_004">group should look like. We provide a very simple template that merely spaces the elements</span></div>
<div style="position:absolute;left:5.00px;top:369.00px" class="cls_004"><span class="cls_004">slightly and sets a few style properties. Let's see the output of this example.</span></div>
<div style="position:absolute;left:5.00px;top:584.26px" class="cls_011"><span class="cls_011">Adorners</span></div>
<div style="position:absolute;left:5.00px;top:614.25px" class="cls_004"><span class="cls_004">An adorner is a special kind of class that is rendered above all UI controls, in what is known</span></div>
<div style="position:absolute;left:5.00px;top:632.25px" class="cls_004"><span class="cls_004">as an adorner layer. Adorner elements in this layer will always be rendered, on top of the</span></div>
<div style="position:absolute;left:5.00px;top:650.25px" class="cls_004"><span class="cls_004">normal WPF controls, regardless of their </span><span class="cls_007">Panel.ZIndex</span><span class="cls_004"> property setting. Each adorner is</span></div>
<div style="position:absolute;left:5.00px;top:668.25px" class="cls_004"><span class="cls_004">bound to an element of type </span><span class="cls_007">UIElement</span><span class="cls_004"> and independently rendered in a position that is</span></div>
<div style="position:absolute;left:5.00px;top:686.25px" class="cls_004"><span class="cls_004">relative to the adorned element.</span></div>
<div style="position:absolute;left:5.00px;top:704.25px" class="cls_004"><span class="cls_004">The purpose of the adorner is to provide certain visual cues to the application user. For</span></div>
<div style="position:absolute;left:5.00px;top:722.25px" class="cls_004"><span class="cls_004">example, we could use an adorner to display a visual representation of UI elements that are</span></div>
<div style="position:absolute;left:5.00px;top:740.25px" class="cls_004"><span class="cls_004">being dragged in a drag and drop operation. Alternatively, we could use an adorner to add</span></div>
<div style="position:absolute;left:5.00px;top:758.25px" class="cls_004"><span class="cls_004">"handles" to a UI control to enable users to resize the element.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:153182px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background193.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">As the adorner is added to the adorner layer, it is the adorner layer that is the parent of the</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">adorner, rather than the adorned element. In order to create a custom adorner, we need to</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">declare a class that extends the </span><span class="cls_007">Adorner</span><span class="cls_004"> class.</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">When creating a custom adorner, we need to be aware that we are responsible for writing</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">the code to render its visuals. However, there are a few different ways to construct our</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">adorner graphics; we can use the </span><span class="cls_007">OnRender</span><span class="cls_004"> or </span><span class="cls_007">OnRenderSizeChanged</span><span class="cls_004"> methods and a</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">drawing context to draw basic lines and shapes, or we can use the </span><span class="cls_007">ArrangeOverride</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">method to arrange .NET controls.</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">Adorners receive events like other .NET controls, although if we don't need to handle them,</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">we can arrange for them to be passed straight through to the adorned element. In these</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">cases, we can set the </span><span class="cls_007">IsHitTestVisible</span><span class="cls_004"> property to </span><span class="cls_007">false</span><span class="cls_004"> and this will enable pass-</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">through hit-testing of the adorned element. Let's see an example of a resizing adorner that</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">lets us resize shapes on a canvas.</span></div>
<div style="position:absolute;left:52.98px;top:243.00px" class="cls_007"><span class="cls_007">using System;</span></div>
<div style="position:absolute;left:52.98px;top:256.50px" class="cls_007"><span class="cls_007">using System.Windows;</span></div>
<div style="position:absolute;left:52.98px;top:270.00px" class="cls_007"><span class="cls_007">using System.Windows.Controls;</span></div>
<div style="position:absolute;left:52.98px;top:283.50px" class="cls_007"><span class="cls_007">using System.Windows.Controls.Primitives;</span></div>
<div style="position:absolute;left:52.98px;top:297.00px" class="cls_007"><span class="cls_007">using System.Windows.Documents;</span></div>
<div style="position:absolute;left:52.98px;top:310.50px" class="cls_007"><span class="cls_007">using System.Windows.Input;</span></div>
<div style="position:absolute;left:52.98px;top:324.00px" class="cls_007"><span class="cls_007">using System.Windows.Media;</span></div>
<div style="position:absolute;left:52.98px;top:351.00px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.Views.Adorners</span></div>
<div style="position:absolute;left:52.98px;top:364.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:378.00px" class="cls_007"><span class="cls_007">public class ResizeAdorner : Adorner</span></div>
<div style="position:absolute;left:67.97px;top:391.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:405.00px" class="cls_007"><span class="cls_007">private VisualCollection visualChildren;</span></div>
<div style="position:absolute;left:82.97px;top:418.50px" class="cls_007"><span class="cls_007">private Thumb top, left, bottom, right;</span></div>
<div style="position:absolute;left:82.97px;top:445.50px" class="cls_007"><span class="cls_007">public ResizeAdorner(UIElement adornedElement) :</span></div>
<div style="position:absolute;left:52.98px;top:459.00px" class="cls_007"><span class="cls_007">base(adornedElement)</span></div>
<div style="position:absolute;left:82.97px;top:472.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:486.00px" class="cls_007"><span class="cls_007">visualChildren = new VisualCollection(this);</span></div>
<div style="position:absolute;left:97.96px;top:499.50px" class="cls_007"><span class="cls_007">top = InitializeThumb(Cursors.SizeNS, Top_DragDelta);</span></div>
<div style="position:absolute;left:97.96px;top:513.00px" class="cls_007"><span class="cls_007">left = InitializeThumb(Cursors.SizeWE, Left_DragDelta);</span></div>
<div style="position:absolute;left:97.96px;top:526.50px" class="cls_007"><span class="cls_007">bottom = InitializeThumb(Cursors.SizeNS, Bottom_DragDelta);</span></div>
<div style="position:absolute;left:97.96px;top:540.00px" class="cls_007"><span class="cls_007">right = InitializeThumb(Cursors.SizeWE, Right_DragDelta);</span></div>
<div style="position:absolute;left:82.97px;top:553.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:580.50px" class="cls_007"><span class="cls_007">private Thumb InitializeThumb(Cursor cursor,</span></div>
<div style="position:absolute;left:97.96px;top:594.00px" class="cls_007"><span class="cls_007">DragDeltaEventHandler eventHandler)</span></div>
<div style="position:absolute;left:82.97px;top:607.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:621.00px" class="cls_007"><span class="cls_007">Thumb thumb = new Thumb();</span></div>
<div style="position:absolute;left:97.96px;top:634.50px" class="cls_007"><span class="cls_007">thumb.BorderBrush = Brushes.Black;</span></div>
<div style="position:absolute;left:97.96px;top:648.00px" class="cls_007"><span class="cls_007">thumb.BorderThickness = new Thickness(1);</span></div>
<div style="position:absolute;left:97.96px;top:661.50px" class="cls_007"><span class="cls_007">thumb.Cursor = cursor;</span></div>
<div style="position:absolute;left:97.96px;top:675.00px" class="cls_007"><span class="cls_007">thumb.DragDelta += eventHandler;</span></div>
<div style="position:absolute;left:97.96px;top:688.50px" class="cls_007"><span class="cls_007">thumb.Height = thumb.Width = 6.0;</span></div>
<div style="position:absolute;left:97.96px;top:702.00px" class="cls_007"><span class="cls_007">visualChildren.Add(thumb);</span></div>
<div style="position:absolute;left:97.96px;top:715.50px" class="cls_007"><span class="cls_007">return thumb;</span></div>
<div style="position:absolute;left:82.97px;top:729.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:756.00px" class="cls_007"><span class="cls_007">private void Top_DragDelta(object sender, DragDeltaEventArgs e)</span></div>
<div style="position:absolute;left:82.97px;top:769.50px" class="cls_007"><span class="cls_007">{</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:153984px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background194.jpg" width=612 height=792></div>
<div style="position:absolute;left:97.96px;top:3.00px" class="cls_007"><span class="cls_007">FrameworkElement adornedElement =</span></div>
<div style="position:absolute;left:52.98px;top:16.50px" class="cls_007"><span class="cls_007">(FrameworkElement)AdornedElement;</span></div>
<div style="position:absolute;left:97.96px;top:30.00px" class="cls_007"><span class="cls_007">adornedElement.Height =</span></div>
<div style="position:absolute;left:112.96px;top:43.50px" class="cls_007"><span class="cls_007">Math.Max(adornedElement.Height - e.VerticalChange, 6);</span></div>
<div style="position:absolute;left:97.96px;top:57.00px" class="cls_007"><span class="cls_007">Canvas.SetTop(adornedElement,</span></div>
<div style="position:absolute;left:112.96px;top:70.50px" class="cls_007"><span class="cls_007">Canvas.GetTop(adornedElement) + e.VerticalChange);</span></div>
<div style="position:absolute;left:82.97px;top:84.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:111.00px" class="cls_007"><span class="cls_007">private void Left_DragDelta(object sender, DragDeltaEventArgs</span></div>
<div style="position:absolute;left:52.98px;top:124.50px" class="cls_007"><span class="cls_007">e)</span></div>
<div style="position:absolute;left:82.97px;top:138.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:151.50px" class="cls_007"><span class="cls_007">FrameworkElement adornedElement =</span></div>
<div style="position:absolute;left:52.98px;top:165.00px" class="cls_007"><span class="cls_007">(FrameworkElement)AdornedElement;</span></div>
<div style="position:absolute;left:97.96px;top:178.50px" class="cls_007"><span class="cls_007">adornedElement.Width =</span></div>
<div style="position:absolute;left:112.96px;top:192.00px" class="cls_007"><span class="cls_007">Math.Max(adornedElement.Width - e.HorizontalChange, 6);</span></div>
<div style="position:absolute;left:97.96px;top:205.50px" class="cls_007"><span class="cls_007">Canvas.SetLeft(adornedElement,</span></div>
<div style="position:absolute;left:112.96px;top:219.00px" class="cls_007"><span class="cls_007">Canvas.GetLeft(adornedElement) + e.HorizontalChange);</span></div>
<div style="position:absolute;left:82.97px;top:232.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:259.50px" class="cls_007"><span class="cls_007">private void Bottom_DragDelta(object sender, DragDeltaEventArgs</span></div>
<div style="position:absolute;left:52.98px;top:273.00px" class="cls_007"><span class="cls_007">e)</span></div>
<div style="position:absolute;left:82.97px;top:286.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:300.00px" class="cls_007"><span class="cls_007">FrameworkElement adornedElement =</span></div>
<div style="position:absolute;left:52.98px;top:313.50px" class="cls_007"><span class="cls_007">(FrameworkElement)AdornedElement;</span></div>
<div style="position:absolute;left:97.96px;top:327.00px" class="cls_007"><span class="cls_007">adornedElement.Height =</span></div>
<div style="position:absolute;left:112.96px;top:340.50px" class="cls_007"><span class="cls_007">Math.Max(adornedElement.Height + e.VerticalChange, 6);</span></div>
<div style="position:absolute;left:82.97px;top:354.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:381.00px" class="cls_007"><span class="cls_007">private void Right_DragDelta(object sender, DragDeltaEventArgs</span></div>
<div style="position:absolute;left:52.98px;top:394.50px" class="cls_007"><span class="cls_007">e)</span></div>
<div style="position:absolute;left:82.97px;top:408.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:421.50px" class="cls_007"><span class="cls_007">FrameworkElement adornedElement =</span></div>
<div style="position:absolute;left:52.98px;top:435.00px" class="cls_007"><span class="cls_007">(FrameworkElement)AdornedElement;</span></div>
<div style="position:absolute;left:97.96px;top:448.50px" class="cls_007"><span class="cls_007">adornedElement.Width =</span></div>
<div style="position:absolute;left:112.96px;top:462.00px" class="cls_007"><span class="cls_007">Math.Max(adornedElement.Width + e.HorizontalChange, 6);</span></div>
<div style="position:absolute;left:82.97px;top:475.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:502.50px" class="cls_007"><span class="cls_007">protected override void OnRender(DrawingContext drawingContext)</span></div>
<div style="position:absolute;left:82.97px;top:516.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:529.50px" class="cls_007"><span class="cls_007">SolidColorBrush brush = new</span></div>
<div style="position:absolute;left:52.98px;top:543.00px" class="cls_007"><span class="cls_007">SolidColorBrush(Colors.Transparent);</span></div>
<div style="position:absolute;left:97.96px;top:556.50px" class="cls_007"><span class="cls_007">Pen pen = new Pen(new SolidColorBrush(Colors.DeepSkyBlue),</span></div>
<div style="position:absolute;left:52.98px;top:570.00px" class="cls_007"><span class="cls_007">1.0);</span></div>
<div style="position:absolute;left:97.96px;top:583.50px" class="cls_007"><span class="cls_007">drawingContext.DrawRectangle(brush, pen,</span></div>
<div style="position:absolute;left:112.96px;top:597.00px" class="cls_007"><span class="cls_007">new Rect(-2, -2, AdornedElement.DesiredSize.Width + 4,</span></div>
<div style="position:absolute;left:112.96px;top:610.50px" class="cls_007"><span class="cls_007">AdornedElement.DesiredSize.Height + 4));</span></div>
<div style="position:absolute;left:82.97px;top:624.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:651.00px" class="cls_007"><span class="cls_007">protected override Size ArrangeOverride(Size finalSize)</span></div>
<div style="position:absolute;left:82.97px;top:664.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:678.00px" class="cls_007"><span class="cls_007">top.Arrange(</span></div>
<div style="position:absolute;left:112.96px;top:691.50px" class="cls_007"><span class="cls_007">new Rect(AdornedElement.DesiredSize.Width / 2 - 3, -8, 6,</span></div>
<div style="position:absolute;left:52.98px;top:705.00px" class="cls_007"><span class="cls_007">6));</span></div>
<div style="position:absolute;left:97.96px;top:718.50px" class="cls_007"><span class="cls_007">left.Arrange(</span></div>
<div style="position:absolute;left:112.96px;top:732.00px" class="cls_007"><span class="cls_007">new Rect(-8, AdornedElement.DesiredSize.Height / 2 - 3, 6,</span></div>
<div style="position:absolute;left:52.98px;top:745.50px" class="cls_007"><span class="cls_007">6));</span></div>
<div style="position:absolute;left:97.96px;top:759.00px" class="cls_007"><span class="cls_007">bottom.Arrange(new Rect(AdornedElement.DesiredSize.Width / 2</span></div>
<div style="position:absolute;left:52.98px;top:772.50px" class="cls_007"><span class="cls_007">- 3,</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:154786px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background195.jpg" width=612 height=792></div>
<div style="position:absolute;left:112.96px;top:3.00px" class="cls_007"><span class="cls_007">AdornedElement.DesiredSize.Height + 2, 6, 6));</span></div>
<div style="position:absolute;left:97.96px;top:16.50px" class="cls_007"><span class="cls_007">right.Arrange(new Rect(AdornedElement.DesiredSize.Width + 2,</span></div>
<div style="position:absolute;left:112.96px;top:30.00px" class="cls_007"><span class="cls_007">AdornedElement.DesiredSize.Height / 2 - 3, 6, 6));</span></div>
<div style="position:absolute;left:97.96px;top:43.50px" class="cls_007"><span class="cls_007">return finalSize;</span></div>
<div style="position:absolute;left:82.97px;top:70.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:97.50px" class="cls_007"><span class="cls_007">protected override int VisualChildrenCount</span></div>
<div style="position:absolute;left:82.97px;top:111.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:124.50px" class="cls_007"><span class="cls_007">get { return visualChildren.Count; }</span></div>
<div style="position:absolute;left:82.97px;top:138.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:165.00px" class="cls_007"><span class="cls_007">protected override Visual GetVisualChild(int index)</span></div>
<div style="position:absolute;left:82.97px;top:178.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:192.00px" class="cls_007"><span class="cls_007">return visualChildren[index];</span></div>
<div style="position:absolute;left:82.97px;top:205.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:219.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:232.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:265.50px" class="cls_004"><span class="cls_004">Before we investigate this class, let's first see how we can use it. Adorners need to be</span></div>
<div style="position:absolute;left:5.00px;top:283.50px" class="cls_004"><span class="cls_004">initialized in code and so, a good place to do this is in the </span><span class="cls_007">UserControl.Loaded</span><span class="cls_004"> method,</span></div>
<div style="position:absolute;left:5.00px;top:301.50px" class="cls_004"><span class="cls_004">when we can be certain that the canvas and its items will have been initialized. Note that as</span></div>
<div style="position:absolute;left:5.00px;top:319.50px" class="cls_004"><span class="cls_004">adorners are purely UI related, initializing them in the control's code behind does not</span></div>
<div style="position:absolute;left:5.00px;top:337.50px" class="cls_004"><span class="cls_004">present any conflict when using MVVM.</span></div>
<div style="position:absolute;left:52.98px;top:360.75px" class="cls_007"><span class="cls_007">Loaded += View_Loaded;</span></div>
<div style="position:absolute;left:52.98px;top:414.75px" class="cls_007"><span class="cls_007">private void View_Loaded(object sender, RoutedEventArgs e)</span></div>
<div style="position:absolute;left:52.98px;top:428.25px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:441.75px" class="cls_007"><span class="cls_007">AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(Canvas);</span></div>
<div style="position:absolute;left:67.97px;top:455.25px" class="cls_007"><span class="cls_007">foreach (UIElement uiElement in Canvas.Children)</span></div>
<div style="position:absolute;left:67.97px;top:468.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:482.25px" class="cls_007"><span class="cls_007">adornerLayer.Add(new ResizeAdorner(uiElement));</span></div>
<div style="position:absolute;left:67.97px;top:495.75px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:509.25px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:542.25px" class="cls_004"><span class="cls_004">We access the adorner layer for the canvas that we will add the adorners to using the</span></div>
<div style="position:absolute;left:5.00px;top:560.25px" class="cls_007"><span class="cls_007">AdornerLayer.GetAdornerLayer</span><span class="cls_004"> method, passing in the canvas as the </span><span class="cls_007">Visual</span><span class="cls_004"> input</span></div>
<div style="position:absolute;left:5.00px;top:578.25px" class="cls_004"><span class="cls_004">parameter. In this example, we attach an instance of our </span><span class="cls_007">ResizeAdorner</span><span class="cls_004"> to each element in</span></div>
<div style="position:absolute;left:5.00px;top:596.25px" class="cls_004"><span class="cls_004">the canvas' </span><span class="cls_007">Children</span><span class="cls_004"> collection and add then add it to the adorner layer.</span></div>
<div style="position:absolute;left:5.00px;top:614.25px" class="cls_004"><span class="cls_004">Now, we just need a </span><span class="cls_007">Canvas</span><span class="cls_004"> panel named </span><span class="cls_007">Canvas</span><span class="cls_004"> and some shapes to resize.</span></div>
<div style="position:absolute;left:52.98px;top:637.50px" class="cls_007"><span class="cls_007"><Canvas Name="Canvas"></span></div>
<div style="position:absolute;left:67.97px;top:651.00px" class="cls_007"><span class="cls_007"><Rectangle Canvas.Top="50" Canvas.Left="50" Fill="Lime"</span></div>
<div style="position:absolute;left:82.97px;top:664.50px" class="cls_007"><span class="cls_007">Stroke="Black" StrokeThickness="3" Width="150" Height="50" /></span></div>
<div style="position:absolute;left:67.97px;top:678.00px" class="cls_007"><span class="cls_007"><Rectangle Canvas.Top="25" Canvas.Left="250" Fill="Yellow"</span></div>
<div style="position:absolute;left:82.97px;top:691.50px" class="cls_007"><span class="cls_007">Stroke="Black" StrokeThickness="3" Width="50" Height="150" /></span></div>
<div style="position:absolute;left:52.98px;top:705.00px" class="cls_007"><span class="cls_007"></Canvas></span></div>
<div style="position:absolute;left:5.00px;top:725.25px" class="cls_004"><span class="cls_004">Let's now return to examine our </span><span class="cls_007">ResizeAdorner</span><span class="cls_004"> class. Note that we have declared the</span></div>
<div style="position:absolute;left:5.00px;top:743.25px" class="cls_007"><span class="cls_007">Adorners</span><span class="cls_004"> namespace within the </span><span class="cls_007">Views</span><span class="cls_004"> project, as this is the only place that it will be used.</span></div>
<div style="position:absolute;left:5.00px;top:761.25px" class="cls_004"><span class="cls_004">Inside the class, we declare the </span><span class="cls_007">VisualCollection</span><span class="cls_004"> object that will contain the visuals that</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:155588px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background196.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">we want to render and then the visuals themselves, in the shape of </span><span class="cls_007">Thumb</span><span class="cls_004"> controls.</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">We've chosen </span><span class="cls_007">Thumb</span><span class="cls_004"> elements because they have built-in functionality that we want to take</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">advantage of. They provide a </span><span class="cls_007">DragDelta</span><span class="cls_004"> event that we will use to register the users' mouse</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">movements when they drag each </span><span class="cls_007">Thumb</span><span class="cls_004">. These controls are normally used internally in the</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_007"><span class="cls_007">Slider</span><span class="cls_004"> and </span><span class="cls_007">ScrollBar</span><span class="cls_004"> controls to enable users to alter values, so they're perfect for our</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">purposes here.</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">We initialize these objects in the constructor, specifying a custom cursor and a different</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_007"><span class="cls_007">DragDelta</span><span class="cls_004"> event handler for each </span><span class="cls_007">Thumb</span><span class="cls_004"> control. In these separate event handlers, we use</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">HorizontalChange</span><span class="cls_004"> or </span><span class="cls_007">VerticalChange</span><span class="cls_004"> properties of the </span><span class="cls_007">DragDeltaEventArgs</span><span class="cls_004"> object to</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">specify the distance and direction of the mouse movement that triggered the event.</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">We use these values to move and/or resize the adorned element by the appropriate amount</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">and direction. Note that we use the </span><span class="cls_007">Math.Max</span><span class="cls_004"> method and the value </span><span class="cls_007">6</span><span class="cls_004"> in our example to</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">ensure that the adorned element cannot be resized smaller than the size of each </span><span class="cls_007">Thumb</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">element and the </span><span class="cls_007">Stroke</span><span class="cls_004"> size of each adorned element.</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">After the four </span><span class="cls_007">DragDelta</span><span class="cls_004"> event handlers, we find two different ways to render our adorner</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">visuals. In the first method, we use the </span><span class="cls_007">DrawingContext</span><span class="cls_004"> object that is passed into the</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_007"><span class="cls_007">OnRender</span><span class="cls_004"> method by the base class to manually draw shapes. This is somewhat similar to</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">the way that we used to draw in the </span><span class="cls_007">Control.Paint</span><span class="cls_004"> event handler methods when using</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_007"><span class="cls_007">Windows.Forms</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_004"><span class="cls_004">In this overridden method, we draw a rectangle that surrounds our element and is four</span></div>
<div style="position:absolute;left:5.00px;top:363.75px" class="cls_004"><span class="cls_004">pixels bigger than it in both dimensions. Note that we define a transparent background for</span></div>
<div style="position:absolute;left:5.00px;top:381.75px" class="cls_004"><span class="cls_004">the drawing brush, as we only want to see the rectangle border. Remember that adorner</span></div>
<div style="position:absolute;left:5.00px;top:399.75px" class="cls_004"><span class="cls_004">graphics are rendered on top of the adorned element, but we do not want to cover it.</span></div>
<div style="position:absolute;left:5.00px;top:417.75px" class="cls_004"><span class="cls_004">In the </span><span class="cls_007">ArrangeOverride</span><span class="cls_004"> method, we use the .NET Framework to render our </span><span class="cls_007">Visual</span></div>
<div style="position:absolute;left:5.00px;top:435.75px" class="cls_004"><span class="cls_004">elements using their </span><span class="cls_007">Arrange</span><span class="cls_004"> methods, as we would in a custom panel. Note that we could</span></div>
<div style="position:absolute;left:5.00px;top:453.75px" class="cls_004"><span class="cls_004">just as easily render our rectangle border in this method using a </span><span class="cls_007">Rectangle</span><span class="cls_004"> element; the</span></div>
<div style="position:absolute;left:5.00px;top:471.75px" class="cls_007"><span class="cls_007">OnRender</span><span class="cls_004"> method was used in this example merely as a demonstration.</span></div>
<div style="position:absolute;left:5.00px;top:489.75px" class="cls_004"><span class="cls_004">In this method, we simply arrange each </span><span class="cls_007">Visual</span><span class="cls_004"> element at the relevant position and size in</span></div>
<div style="position:absolute;left:5.00px;top:507.75px" class="cls_004"><span class="cls_004">turn. Calculating the appropriate positions can be achieved simply by dividing the width or</span></div>
<div style="position:absolute;left:5.00px;top:525.75px" class="cls_004"><span class="cls_004">height of each adorned element in half and subtracting half of the width or height of each</span></div>
<div style="position:absolute;left:5.00px;top:543.75px" class="cls_004"><span class="cls_004">thumb element.</span></div>
<div style="position:absolute;left:5.00px;top:561.75px" class="cls_004"><span class="cls_004">Finally, we get to the protected overridden </span><span class="cls_007">VisualChildrenCount</span><span class="cls_004"> property and</span></div>
<div style="position:absolute;left:5.00px;top:579.75px" class="cls_007"><span class="cls_007">GetVisualChild</span><span class="cls_004"> method. The </span><span class="cls_007">Adorner</span><span class="cls_004"> class extends the </span><span class="cls_007">FrameworkElement</span><span class="cls_004"> class and that</span></div>
<div style="position:absolute;left:5.00px;top:597.75px" class="cls_004"><span class="cls_004">will normally return either zero or one from the </span><span class="cls_007">VisualChildrenCount</span><span class="cls_004"> property, as each</span></div>
<div style="position:absolute;left:5.00px;top:615.75px" class="cls_004"><span class="cls_004">instance is normally represented by either no visual, or a single rendered visual.</span></div>
<div style="position:absolute;left:5.00px;top:633.75px" class="cls_004"><span class="cls_004">In our case and other situations when a derived class has multiple visuals to render, it is a</span></div>
<div style="position:absolute;left:5.00px;top:651.75px" class="cls_004"><span class="cls_004">requirement of the layout system that the correct number of visuals is specified. For</span></div>
<div style="position:absolute;left:5.00px;top:669.75px" class="cls_004"><span class="cls_004">example, if we always returned the value </span><span class="cls_007">2</span><span class="cls_004"> from this property, then only two of our thumbs</span></div>
<div style="position:absolute;left:5.00px;top:687.75px" class="cls_004"><span class="cls_004">would be rendered on the screen.</span></div>
<div style="position:absolute;left:5.00px;top:705.75px" class="cls_004"><span class="cls_004">Likewise, we also need to return the correct item from our visual collection when requested</span></div>
<div style="position:absolute;left:5.00px;top:723.75px" class="cls_004"><span class="cls_004">to from the </span><span class="cls_007">GetVisualChild</span><span class="cls_004"> method. If, for example, we always returned the first visual</span></div>
<div style="position:absolute;left:5.00px;top:741.75px" class="cls_004"><span class="cls_004">from our collection, then only that visual would be rendered, as the same visual cannot be</span></div>
<div style="position:absolute;left:5.00px;top:759.75px" class="cls_004"><span class="cls_004">rendered more than once. Let's see what our adorners look like when rendered above each</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:156390px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background197.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">of our shapes.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:157192px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background198.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_008"><span class="cls_008">Modifying existing controls</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">When we find that the wide range of existing controls do not quite meet our needs, we</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">might think that we need to create some new ones, as we would with other technologies.</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">When using other UI languages, this might be the case, but with WPF, this is not necessarily</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">correct, as it provides a number of ways to modify the existing controls to suit our</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">requirements.</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">As we found out earlier, all classes that extend the </span><span class="cls_007">FrameworkElement</span><span class="cls_004"> class have access to</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">the framework's styling capabilities and those that extend the </span><span class="cls_007">Control</span><span class="cls_004"> class can have their</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">appearance totally changed through their </span><span class="cls_007">ControlTemplate</span><span class="cls_004"> property. All of the existing WPF</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">controls extend these base cases and so, possess these abilities.</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">In addition to these capabilities that enable us to change the look of the pre-existing WPF</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">controls, we are also able to leverage the power of Attached Properties to add additional</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">functionality to them too. In this section, we will investigate these different ways of</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">modifying the existing controls.</span></div>
<div style="position:absolute;left:5.00px;top:273.01px" class="cls_011"><span class="cls_011">Styling</span></div>
<div style="position:absolute;left:5.00px;top:303.00px" class="cls_004"><span class="cls_004">Setting the various properties of a control is the simplest way to alter its look and enables</span></div>
<div style="position:absolute;left:5.00px;top:321.00px" class="cls_004"><span class="cls_004">us to make either minor, or more dramatic changes to it. As most UI elements extend the</span></div>
<div style="position:absolute;left:5.00px;top:339.00px" class="cls_007"><span class="cls_007">Control</span><span class="cls_004"> class, they mostly share the same properties that affect their appearance and</span></div>
<div style="position:absolute;left:5.00px;top:357.00px" class="cls_004"><span class="cls_004">alignment. When defining styles for controls, we should specify their type in the </span><span class="cls_007">TargetType</span></div>
<div style="position:absolute;left:5.00px;top:375.00px" class="cls_004"><span class="cls_004">property, as this helps the compiler to verify that the properties that we are setting actually</span></div>
<div style="position:absolute;left:5.00px;top:393.00px" class="cls_004"><span class="cls_004">exist in the class.</span></div>
<div style="position:absolute;left:52.98px;top:416.25px" class="cls_007"><span class="cls_007"><Button Content="Go"></span></div>
<div style="position:absolute;left:67.97px;top:429.75px" class="cls_007"><span class="cls_007"><Button.Style></span></div>
<div style="position:absolute;left:82.97px;top:443.25px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type Button}"></span></div>
<div style="position:absolute;left:97.96px;top:456.75px" class="cls_007"><span class="cls_007"><Setter Property="Foreground" Value="Green" /></span></div>
<div style="position:absolute;left:97.96px;top:470.25px" class="cls_007"><span class="cls_007"><Setter Property="Background" Value="White" /></span></div>
<div style="position:absolute;left:82.97px;top:483.75px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:67.97px;top:497.25px" class="cls_007"><span class="cls_007"></Button.Style></span></div>
<div style="position:absolute;left:52.98px;top:510.75px" class="cls_007"><span class="cls_007"></Button></span></div>
<div style="position:absolute;left:5.00px;top:531.00px" class="cls_004"><span class="cls_004">Failing to do so will result in the compiler stating that the member is not recognized or is not</span></div>
<div style="position:absolute;left:5.00px;top:549.00px" class="cls_004"><span class="cls_004">accessible. In these cases, we will need to specify the class type as well, in the format</span></div>
<div style="position:absolute;left:5.00px;top:567.00px" class="cls_007"><span class="cls_007">ClassName.PropertyName</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:52.98px;top:590.25px" class="cls_007"><span class="cls_007"><Button Content="Go"></span></div>
<div style="position:absolute;left:67.97px;top:603.75px" class="cls_007"><span class="cls_007"><Button.Style></span></div>
<div style="position:absolute;left:82.97px;top:617.25px" class="cls_007"><span class="cls_007"><Style></span></div>
<div style="position:absolute;left:97.96px;top:630.75px" class="cls_007"><span class="cls_007"><Setter Property="Button.Foreground" Value="Green" /></span></div>
<div style="position:absolute;left:97.96px;top:644.25px" class="cls_007"><span class="cls_007"><Setter Property="Button.Background" Value="White" /></span></div>
<div style="position:absolute;left:82.97px;top:657.75px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:67.97px;top:671.25px" class="cls_007"><span class="cls_007"></Button.Style></span></div>
<div style="position:absolute;left:52.98px;top:684.75px" class="cls_007"><span class="cls_007"></Button></span></div>
<div style="position:absolute;left:5.00px;top:705.00px" class="cls_004"><span class="cls_004">One really useful property that the </span><span class="cls_007">Style</span><span class="cls_004"> class declares is the </span><span class="cls_007">BasedOn</span><span class="cls_004"> property. Using this</span></div>
<div style="position:absolute;left:5.00px;top:723.00px" class="cls_004"><span class="cls_004">property, we can base our styles on other styles and this enables us to create a number of</span></div>
<div style="position:absolute;left:5.00px;top:741.00px" class="cls_004"><span class="cls_004">incrementally different versions. Let's highlight this with an example.</span></div>
<div style="position:absolute;left:52.98px;top:764.25px" class="cls_007"><span class="cls_007"><Style x:Key="TextBoxStyle" TargetType="{x:Type TextBox}"></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:157994px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background199.jpg" width=612 height=792></div>
<div style="position:absolute;left:67.97px;top:3.00px" class="cls_007"><span class="cls_007"><Setter Property="SnapsToDevicePixels" Value="True" /></span></div>
<div style="position:absolute;left:67.97px;top:16.50px" class="cls_007"><span class="cls_007"><Setter Property="Margin" Value="0,0,0,5" /></span></div>
<div style="position:absolute;left:67.97px;top:30.00px" class="cls_007"><span class="cls_007"><Setter Property="Padding" Value="1.5,2" /></span></div>
<div style="position:absolute;left:67.97px;top:43.50px" class="cls_007"><span class="cls_007"><Setter Property="TextWrapping" Value="Wrap" /></span></div>
<div style="position:absolute;left:52.98px;top:57.00px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:52.98px;top:70.50px" class="cls_007"><span class="cls_007"><Style x:Key="ReadOnlyTextBoxStyle" TargetType="{x:Type TextBox}"</span></div>
<div style="position:absolute;left:67.97px;top:84.00px" class="cls_007"><span class="cls_007">BasedOn="{StaticResource TextBoxStyle}"></span></div>
<div style="position:absolute;left:67.97px;top:97.50px" class="cls_007"><span class="cls_007"><Setter Property="IsReadOnly" Value="True" /></span></div>
<div style="position:absolute;left:67.97px;top:111.00px" class="cls_007"><span class="cls_007"><Setter Property="Cursor" Value="Arrow" /></span></div>
<div style="position:absolute;left:52.98px;top:124.50px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:5.00px;top:144.75px" class="cls_004"><span class="cls_004">Here, we define a simple style for the textboxes in our application. We name it</span></div>
<div style="position:absolute;left:5.00px;top:162.75px" class="cls_007"><span class="cls_007">TextBoxStyle</span><span class="cls_004"> and then reference it in the </span><span class="cls_007">BasedOn</span><span class="cls_004"> property of the second style. This means</span></div>
<div style="position:absolute;left:5.00px;top:180.75px" class="cls_004"><span class="cls_004">that all of the property setters and triggers declared in the first style will also apply to the</span></div>
<div style="position:absolute;left:5.00px;top:198.75px" class="cls_004"><span class="cls_004">bottom style. In the second style, we add a few further setters to make the applied textbox</span></div>
<div style="position:absolute;left:5.00px;top:216.75px" class="cls_004"><span class="cls_004">read-only.</span></div>
<div style="position:absolute;left:5.00px;top:234.75px" class="cls_004"><span class="cls_004">One last point to note is that if we wanted to base a style on the default style of a control,</span></div>
<div style="position:absolute;left:5.00px;top:252.75px" class="cls_004"><span class="cls_004">we can use the value that we normally enter into the </span><span class="cls_007">TargetType</span><span class="cls_004"> property as the key to</span></div>
<div style="position:absolute;left:5.00px;top:270.75px" class="cls_004"><span class="cls_004">identify the style that we want to base the new style on.</span></div>
<div style="position:absolute;left:52.98px;top:294.00px" class="cls_007"><span class="cls_007"><Style x:Key="ExtendedTextBoxStyle" TargetType="{x:Type TextBox}"</span></div>
<div style="position:absolute;left:67.97px;top:307.50px" class="cls_007"><span class="cls_007">BasedOn="{StaticResource {x:Type TextBox}}"></span></div>
<div style="position:absolute;left:52.98px;top:334.50px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:5.00px;top:354.00px" class="cls_013"><span class="cls_013">Being resourceful</span></div>
<div style="position:absolute;left:5.00px;top:379.50px" class="cls_004"><span class="cls_004">Styles are most often declared in the various </span><span class="cls_007">Resources</span><span class="cls_004"> dictionaries of the application,</span></div>
<div style="position:absolute;left:5.00px;top:397.50px" class="cls_004"><span class="cls_004">along with various templates and application colors and brushes. The </span><span class="cls_007">Resources</span><span class="cls_004"> property is</span></div>
<div style="position:absolute;left:5.00px;top:415.50px" class="cls_004"><span class="cls_004">of type </span><span class="cls_007">ResourceDictionary</span><span class="cls_004"> and declared in the </span><span class="cls_007">FrameworkElement</span><span class="cls_004"> class and so virtually all</span></div>
<div style="position:absolute;left:5.00px;top:433.50px" class="cls_004"><span class="cls_004">UI elements inherit it and can therefore host our styles and other resources.</span></div>
<div style="position:absolute;left:5.00px;top:451.50px" class="cls_004"><span class="cls_004">Although the </span><span class="cls_007">Resources</span><span class="cls_004"> property is of type </span><span class="cls_007">ResourceDictionary</span><span class="cls_004">, we do not need to</span></div>
<div style="position:absolute;left:5.00px;top:469.50px" class="cls_004"><span class="cls_004">explicitly declare this element.</span></div>
<div style="position:absolute;left:52.98px;top:492.75px" class="cls_007"><span class="cls_007"><Application.Resources></span></div>
<div style="position:absolute;left:67.97px;top:506.25px" class="cls_007"><span class="cls_007"><ResourceDictionary></span></div>
<div style="position:absolute;left:82.97px;top:519.75px" class="cls_007"><span class="cls_007"><!-- Add resources here --></span></div>
<div style="position:absolute;left:67.97px;top:533.25px" class="cls_007"><span class="cls_007"></ResourceDictionary></span></div>
<div style="position:absolute;left:52.98px;top:546.75px" class="cls_007"><span class="cls_007"></Application.Resources></span></div>
<div style="position:absolute;left:5.00px;top:567.00px" class="cls_004"><span class="cls_004">While there are some occasions when we do need to explicitly declare the</span></div>
<div style="position:absolute;left:5.00px;top:585.00px" class="cls_007"><span class="cls_007">ResourceDictionary</span><span class="cls_004">, it will be implicitly declared for us if we do not.</span></div>
<div style="position:absolute;left:52.98px;top:608.25px" class="cls_007"><span class="cls_007"><Application.Resources></span></div>
<div style="position:absolute;left:67.97px;top:621.75px" class="cls_007"><span class="cls_007"><!-- Add Resources here --></span></div>
<div style="position:absolute;left:52.98px;top:635.25px" class="cls_007"><span class="cls_007"></Application.Resources></span></div>
<div style="position:absolute;left:5.00px;top:655.50px" class="cls_004"><span class="cls_004">Every resource in each collection must have a key that uniquely identifies them. We use the</span></div>
<div style="position:absolute;left:5.00px;top:673.50px" class="cls_007"><span class="cls_007">x:Key</span><span class="cls_004"> directive to explicitly set this key, however it can also be set implicitly as well. When</span></div>
<div style="position:absolute;left:5.00px;top:691.50px" class="cls_004"><span class="cls_004">we declare styles in any </span><span class="cls_007">Resources</span><span class="cls_004"> section, we can specify the </span><span class="cls_007">TargetType</span><span class="cls_004"> value, in which</span></div>
<div style="position:absolute;left:5.00px;top:709.50px" class="cls_004"><span class="cls_004">case the style will be implicitly applied to elements of the correct type that are in scope of</span></div>
<div style="position:absolute;left:5.00px;top:727.50px" class="cls_004"><span class="cls_004">the style.</span></div>
<div style="position:absolute;left:52.98px;top:750.75px" class="cls_007"><span class="cls_007"><Resources></span></div>
<div style="position:absolute;left:67.97px;top:764.25px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type Button}"></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:158796px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background200.jpg" width=612 height=792></div>
<div style="position:absolute;left:82.97px;top:3.00px" class="cls_007"><span class="cls_007"><Setter Property="Foreground" Value="Green" /></span></div>
<div style="position:absolute;left:82.97px;top:16.50px" class="cls_007"><span class="cls_007"><Setter Property="Background" Value="White" /></span></div>
<div style="position:absolute;left:67.97px;top:30.00px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:52.98px;top:43.50px" class="cls_007"><span class="cls_007"></Resources></span></div>
<div style="position:absolute;left:5.00px;top:63.75px" class="cls_004"><span class="cls_004">In this case, the value for the </span><span class="cls_007">x:Key</span><span class="cls_004"> directive is implicitly set to </span><span class="cls_007">{x:Type Button}</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:81.75px" class="cls_004"><span class="cls_004">Alternatively, we can set the </span><span class="cls_007">x:Key</span><span class="cls_004"> directive explicitly, so that the style must also be applied</span></div>
<div style="position:absolute;left:5.00px;top:99.75px" class="cls_004"><span class="cls_004">explicitly.</span></div>
<div style="position:absolute;left:52.98px;top:123.00px" class="cls_007"><span class="cls_007"><Resources></span></div>
<div style="position:absolute;left:67.97px;top:136.50px" class="cls_007"><span class="cls_007"><Style x:Key="ButtonStyle"></span></div>
<div style="position:absolute;left:82.97px;top:150.00px" class="cls_007"><span class="cls_007"><Setter Property="Button.Foreground" Value="Green" /></span></div>
<div style="position:absolute;left:82.97px;top:163.50px" class="cls_007"><span class="cls_007"><Setter Property="Button.Background" Value="White" /></span></div>
<div style="position:absolute;left:67.97px;top:177.00px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:52.98px;top:190.50px" class="cls_007"><span class="cls_007"></Resources></span></div>
<div style="position:absolute;left:52.98px;top:217.50px" class="cls_007"><span class="cls_007"><Button Style="{StaticResource ButtonStyle}" Content="Go" /></span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">Styles can have both values set as well, as shown in the following code:</span></div>
<div style="position:absolute;left:52.98px;top:261.00px" class="cls_007"><span class="cls_007"><Resources></span></div>
<div style="position:absolute;left:67.97px;top:274.50px" class="cls_007"><span class="cls_007"><Style x:Key="ButtonStyle" TargetType="{x:Type Button}"></span></div>
<div style="position:absolute;left:82.97px;top:288.00px" class="cls_007"><span class="cls_007"><Setter Property="Foreground" Value="Green" /></span></div>
<div style="position:absolute;left:82.97px;top:301.50px" class="cls_007"><span class="cls_007"><Setter Property="Background" Value="White" /></span></div>
<div style="position:absolute;left:67.97px;top:315.00px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:52.98px;top:328.50px" class="cls_007"><span class="cls_007"></Resources></span></div>
<div style="position:absolute;left:5.00px;top:348.75px" class="cls_004"><span class="cls_004">But a compilation error will be thrown if neither value is set:</span></div>
<div style="position:absolute;left:52.98px;top:372.00px" class="cls_007"><span class="cls_007"><Resources></span></div>
<div style="position:absolute;left:67.97px;top:385.50px" class="cls_007"><span class="cls_007"><Style></span></div>
<div style="position:absolute;left:82.97px;top:399.00px" class="cls_007"><span class="cls_007"><Setter Property="Foreground" Value="Green" /></span></div>
<div style="position:absolute;left:82.97px;top:412.50px" class="cls_007"><span class="cls_007"><Setter Property="Background" Value="White" /></span></div>
<div style="position:absolute;left:67.97px;top:426.00px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:52.98px;top:439.50px" class="cls_007"><span class="cls_007"></Resources></span></div>
<div style="position:absolute;left:5.00px;top:459.75px" class="cls_004"><span class="cls_004">The preceding XAML would result in the following compilation error:</span></div>
<div style="position:absolute;left:52.98px;top:482.25px" class="cls_009"><span class="cls_009">The member "Foreground" is not recognized or is not accessible.</span></div>
<div style="position:absolute;left:52.98px;top:496.50px" class="cls_009"><span class="cls_009">The member "Background" is not recognized or is not accessible.</span></div>
<div style="position:absolute;left:5.00px;top:517.50px" class="cls_004"><span class="cls_004">When a </span><span class="cls_007">StaticResource</span><span class="cls_004"> with a specific key is requested, the lookup process first looks in</span></div>
<div style="position:absolute;left:5.00px;top:535.50px" class="cls_004"><span class="cls_004">the local control; if it has a style and that style has a resource dictionary, it checks that first;</span></div>
<div style="position:absolute;left:5.00px;top:553.50px" class="cls_004"><span class="cls_004">if there is no item with a matching key, it next looks in the resource collection of the control</span></div>
<div style="position:absolute;left:5.00px;top:571.50px" class="cls_004"><span class="cls_004">itself.</span></div>
<div style="position:absolute;left:5.00px;top:589.50px" class="cls_004"><span class="cls_004">If there is still no match, the lookup process checks the resource dictionaries of each parent</span></div>
<div style="position:absolute;left:5.00px;top:607.50px" class="cls_004"><span class="cls_004">control until it reaches the </span><span class="cls_007">MainWindow.xaml</span><span class="cls_004"> file. If it still does not find a match, then it will</span></div>
<div style="position:absolute;left:5.00px;top:625.50px" class="cls_004"><span class="cls_004">look in the application </span><span class="cls_007">Resources</span><span class="cls_004"> section in the </span><span class="cls_007">App.xaml</span><span class="cls_004"> file.</span></div>
<div style="position:absolute;left:5.00px;top:643.50px" class="cls_007"><span class="cls_007">StaticResource</span><span class="cls_004"> lookups occur once upon initialization and will suit our requirements for</span></div>
<div style="position:absolute;left:5.00px;top:661.50px" class="cls_004"><span class="cls_004">most of the time. When using a </span><span class="cls_007">StaticResource</span><span class="cls_004"> to reference one resource that is to be</span></div>
<div style="position:absolute;left:5.00px;top:679.50px" class="cls_004"><span class="cls_004">used within another resource, the resource being used must be declared beforehand. That</span></div>
<div style="position:absolute;left:5.00px;top:697.50px" class="cls_004"><span class="cls_004">is to say that a </span><span class="cls_007">StaticResource</span><span class="cls_004"> lookup from one resource cannot reference another</span></div>
<div style="position:absolute;left:5.00px;top:715.50px" class="cls_004"><span class="cls_004">resource that is declared after it in the resource dictionary.</span></div>
<div style="position:absolute;left:52.98px;top:738.75px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type Button}"></span></div>
<div style="position:absolute;left:67.97px;top:752.25px" class="cls_007"><span class="cls_007"><Setter Property="Foreground" Value="{StaticResource RedBrush}"</span></div>
<div style="position:absolute;left:52.98px;top:765.75px" class="cls_007"><span class="cls_007">/></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:159598px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background201.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:3.00px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:52.98px;top:16.50px" class="cls_007"><span class="cls_007"><SolidColorBrush x:Key="RedBrush" Color="Red" /></span></div>
<div style="position:absolute;left:5.00px;top:36.75px" class="cls_004"><span class="cls_004">The preceding XAML would result in the following error:</span></div>
<div style="position:absolute;left:52.98px;top:60.00px" class="cls_009"><span class="cls_009">The resource "RedBrush" could not be resolved.</span></div>
<div style="position:absolute;left:5.00px;top:81.00px" class="cls_004"><span class="cls_004">Simply moving the declaration of the brush before the style would clear this error and get</span></div>
<div style="position:absolute;left:5.00px;top:99.00px" class="cls_004"><span class="cls_004">the application running again. However, there are certain situations when using a</span></div>
<div style="position:absolute;left:5.00px;top:117.00px" class="cls_007"><span class="cls_007">StaticResource</span><span class="cls_004"> to reference a resource isn't suitable. For example, we might need our</span></div>
<div style="position:absolute;left:5.00px;top:135.00px" class="cls_004"><span class="cls_004">styles to update during runtime in response to some programmatic or user interaction, such</span></div>
<div style="position:absolute;left:5.00px;top:153.00px" class="cls_004"><span class="cls_004">as a changing of the computer theme.</span></div>
<div style="position:absolute;left:5.00px;top:171.00px" class="cls_004"><span class="cls_004">In these cases, we can use a </span><span class="cls_007">DynamicResource</span><span class="cls_004"> to reference our resources and can rest</span></div>
<div style="position:absolute;left:5.00px;top:189.00px" class="cls_004"><span class="cls_004">assured that our styles will update when the relevant resources are changed. Note that the</span></div>
<div style="position:absolute;left:5.00px;top:207.00px" class="cls_004"><span class="cls_004">resource value is not actually looked up until it is actually requested, so this is perfect for</span></div>
<div style="position:absolute;left:5.00px;top:225.00px" class="cls_004"><span class="cls_004">resources that will not be ready until after the application start. Note the following altered</span></div>
<div style="position:absolute;left:5.00px;top:243.00px" class="cls_004"><span class="cls_004">example.</span></div>
<div style="position:absolute;left:52.98px;top:266.25px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type Button}"></span></div>
<div style="position:absolute;left:67.97px;top:279.75px" class="cls_007"><span class="cls_007"><Setter Property="Foreground" Value="{DynamicResource RedBrush}"</span></div>
<div style="position:absolute;left:52.98px;top:293.25px" class="cls_007"><span class="cls_007">/></span></div>
<div style="position:absolute;left:52.98px;top:306.75px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:52.98px;top:320.25px" class="cls_007"><span class="cls_007"><SolidColorBrush x:Key="RedBrush" Color="Red" /></span></div>
<div style="position:absolute;left:5.00px;top:340.50px" class="cls_004"><span class="cls_004">In this case, there will be no compilation error, as the </span><span class="cls_007">DynamicResource</span><span class="cls_004"> will retrieve the</span></div>
<div style="position:absolute;left:5.00px;top:358.50px" class="cls_004"><span class="cls_004">value whenever it is set. While it's great to have this ability, it's important not to abuse it, as</span></div>
<div style="position:absolute;left:5.00px;top:376.50px" class="cls_004"><span class="cls_004">using the </span><span class="cls_007">DynamicResource</span><span class="cls_004"> will negatively affect performance. This is because they</span></div>
<div style="position:absolute;left:5.00px;top:394.50px" class="cls_004"><span class="cls_004">repeatedly lookup the value each time it is requested, whether the values have changed or</span></div>
<div style="position:absolute;left:5.00px;top:412.50px" class="cls_004"><span class="cls_004">not. For this reason, we should only ever use a </span><span class="cls_007">DynamicResource</span><span class="cls_004"> if we really need to.</span></div>
<div style="position:absolute;left:5.00px;top:430.50px" class="cls_004"><span class="cls_004">One final point about resource styles to mention here relates to scope. While this topic has</span></div>
<div style="position:absolute;left:5.00px;top:448.50px" class="cls_004"><span class="cls_004">been mentioned elsewhere in this book, it is outlined again here as it is essential to</span></div>
<div style="position:absolute;left:5.00px;top:466.50px" class="cls_004"><span class="cls_004">understand the resource lookup procedure. Application resources that are declared in the</span></div>
<div style="position:absolute;left:5.00px;top:484.50px" class="cls_007"><span class="cls_007">App.xaml</span><span class="cls_004"> file are available application wide, so this is a great place to declare our common</span></div>
<div style="position:absolute;left:5.00px;top:502.50px" class="cls_004"><span class="cls_004">styles.</span></div>
<div style="position:absolute;left:5.00px;top:520.50px" class="cls_004"><span class="cls_004">However, this is one of the furthest removed places that we can declare our styles, ignoring</span></div>
<div style="position:absolute;left:5.00px;top:538.50px" class="cls_004"><span class="cls_004">external resource dictionaries and theme styles. In general, the rule is that given a resource</span></div>
<div style="position:absolute;left:5.00px;top:556.50px" class="cls_004"><span class="cls_004">identifier conflict, the most local resources override those that are declared further away.</span></div>
<div style="position:absolute;left:5.00px;top:574.50px" class="cls_004"><span class="cls_004">Therefore, we can define our default styles in the application resources, but retain the</span></div>
<div style="position:absolute;left:5.00px;top:592.50px" class="cls_004"><span class="cls_004">ability to override them locally.</span></div>
<div style="position:absolute;left:5.00px;top:610.50px" class="cls_004"><span class="cls_004">Conversely, locally declared styles without an </span><span class="cls_007">x:Key</span><span class="cls_004"> directive will be implicitly applied locally,</span></div>
<div style="position:absolute;left:5.00px;top:628.50px" class="cls_004"><span class="cls_004">but will not be applied to elements of the relevant type that are declared externally. We can</span></div>
<div style="position:absolute;left:5.00px;top:646.50px" class="cls_004"><span class="cls_004">therefore declare implicit styles in the </span><span class="cls_007">Resources</span><span class="cls_004"> section of a panel for example and they</span></div>
<div style="position:absolute;left:5.00px;top:664.50px" class="cls_004"><span class="cls_004">will only be applied to elements of the relative type within the panel.</span></div>
<div style="position:absolute;left:5.00px;top:681.75px" class="cls_013"><span class="cls_013">Merging resources</span></div>
<div style="position:absolute;left:5.00px;top:707.25px" class="cls_004"><span class="cls_004">If we have a large application and our application resources are becoming overcrowded,</span></div>
<div style="position:absolute;left:5.00px;top:725.25px" class="cls_004"><span class="cls_004">we have the option of splitting our default colors, brushes, styles, templates and other</span></div>
<div style="position:absolute;left:5.00px;top:743.25px" class="cls_004"><span class="cls_004">resources into different files. In addition to organizational and maintenance benefits, this</span></div>
<div style="position:absolute;left:5.00px;top:761.25px" class="cls_004"><span class="cls_004">also enables our main resource files to be shared amongst our other applications and so,</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:160400px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background202.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">this promotes reusability too.</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">In order to do this, we first need one or more additional resource files. We can add an</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">additional resource file using Visual Studio, by right-clicking on the relevant project and</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">selecting the </span><span class="cls_005">Add</span><span class="cls_004"> option and then the </span><span class="cls_005">Resource Dictionary...</span><span class="cls_004"> option. Upon executing this</span></div>
<div style="position:absolute;left:5.00px;top:76.50px" class="cls_004"><span class="cls_004">command, we will be provided with a file like this.</span></div>
<div style="position:absolute;left:52.98px;top:99.75px" class="cls_007"><span class="cls_007"><ResourceDictionary</span></div>
<div style="position:absolute;left:67.97px;top:113.25px" class="cls_007"><span class="cls_007">xmlns="</span><A HREF="http://schemas.microsoft.com/winfx/2006/xaml/presentation"/">http://schemas.microsoft.com/winfx/2006/xaml/presentation"</A> </div>
<div style="position:absolute;left:67.97px;top:126.75px" class="cls_007"><span class="cls_007">xmlns:x="</span><A HREF="http://schemas.microsoft.com/winfx/2006/xaml"/">http://schemas.microsoft.com/winfx/2006/xaml"</A>></div>
<div style="position:absolute;left:52.98px;top:153.75px" class="cls_007"><span class="cls_007"></ResourceDictionary></span></div>
<div style="position:absolute;left:5.00px;top:186.75px" class="cls_004"><span class="cls_004">This is one of the occasions when we do need to explicitly declare the </span><span class="cls_007">ResourceDictionary</span></div>
<div style="position:absolute;left:5.00px;top:204.75px" class="cls_004"><span class="cls_004">element. Once we have transferred our styles or other resources to this file, we can merge</span></div>
<div style="position:absolute;left:5.00px;top:222.75px" class="cls_004"><span class="cls_004">it into our main application resources file like this:</span></div>
<div style="position:absolute;left:52.98px;top:246.00px" class="cls_007"><span class="cls_007"><Application.Resources></span></div>
<div style="position:absolute;left:67.97px;top:259.50px" class="cls_007"><span class="cls_007"><ResourceDictionary></span></div>
<div style="position:absolute;left:82.97px;top:273.00px" class="cls_007"><span class="cls_007"><!-- Add Resources here... --></span></div>
<div style="position:absolute;left:82.97px;top:286.50px" class="cls_007"><span class="cls_007"><ResourceDictionary.MergedDictionaries></span></div>
<div style="position:absolute;left:97.96px;top:300.00px" class="cls_007"><span class="cls_007"><ResourceDictionary Source="Default Styles.xaml" /></span></div>
<div style="position:absolute;left:97.96px;top:313.50px" class="cls_007"><span class="cls_007"><ResourceDictionary Source="Default Templates.xaml" /></span></div>
<div style="position:absolute;left:82.97px;top:327.00px" class="cls_007"><span class="cls_007"></ResourceDictionary.MergedDictionaries></span></div>
<div style="position:absolute;left:82.97px;top:340.50px" class="cls_007"><span class="cls_007"><!-- ... or add resources here, but not in both locations --></span></div>
<div style="position:absolute;left:67.97px;top:354.00px" class="cls_007"><span class="cls_007"></ResourceDictionary></span></div>
<div style="position:absolute;left:52.98px;top:367.50px" class="cls_007"><span class="cls_007"></Application.Resources></span></div>
<div style="position:absolute;left:5.00px;top:387.75px" class="cls_004"><span class="cls_004">Note that we do not specify the </span><span class="cls_007">x:Key</span><span class="cls_004"> directive for this resource dictionary. In fact, if we did</span></div>
<div style="position:absolute;left:5.00px;top:405.75px" class="cls_004"><span class="cls_004">specify this value on the dictionary, we would receive a compilation error:</span></div>
<div style="position:absolute;left:52.98px;top:428.25px" class="cls_009"><span class="cls_009">The "Key" attribute can only be used on an element that is</span></div>
<div style="position:absolute;left:52.98px;top:441.75px" class="cls_009"><span class="cls_009">contained</span></div>
<div style="position:absolute;left:67.97px;top:469.50px" class="cls_009"><span class="cls_009">in "IDictionary".</span></div>
<div style="position:absolute;left:5.00px;top:490.50px" class="cls_004"><span class="cls_004">Note also that we can set the </span><span class="cls_007">ResourceDictionary.MergedDictionaries</span><span class="cls_004"> value either above</span></div>
<div style="position:absolute;left:5.00px;top:508.50px" class="cls_004"><span class="cls_004">or below our locally declared resources, but not anywhere in the middle of them. Within this</span></div>
<div style="position:absolute;left:5.00px;top:526.50px" class="cls_004"><span class="cls_004">property, we can declare another </span><span class="cls_007">ResourceDictionary</span><span class="cls_004"> element for each external resource</span></div>
<div style="position:absolute;left:5.00px;top:544.50px" class="cls_004"><span class="cls_004">file that we want to merge and specify its location using a </span><span class="cls_005">Uniform Resource Identifier</span></div>
<div style="position:absolute;left:5.00px;top:563.25px" class="cls_004"><span class="cls_004">(</span><span class="cls_005">URI</span><span class="cls_004">) in the </span><span class="cls_007">Source</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:5.00px;top:582.00px" class="cls_004"><span class="cls_004">If our external resource files reside in our startup project with our </span><span class="cls_007">App.xaml</span><span class="cls_004"> file, we can</span></div>
<div style="position:absolute;left:5.00px;top:600.00px" class="cls_004"><span class="cls_004">reference them with relative paths, as shown in the preceding example. Otherwise, we will</span></div>
<div style="position:absolute;left:5.00px;top:618.00px" class="cls_004"><span class="cls_004">need to use the Pack URI notation. To reference a resource file from a referenced</span></div>
<div style="position:absolute;left:5.00px;top:636.00px" class="cls_004"><span class="cls_004">assembly, we would need to use the following format:</span></div>
<div style="position:absolute;left:52.98px;top:659.25px" class="cls_007"><span class="cls_007">pack://application:,,,/ReferencedAssembly;component/ResourceFile.xa</span></div>
<div style="position:absolute;left:52.98px;top:672.75px" class="cls_007"><span class="cls_007">ml</span></div>
<div style="position:absolute;left:5.00px;top:693.00px" class="cls_004"><span class="cls_004">In our case, assuming that we had some resource files in a folder named </span><span class="cls_007">Styles</span><span class="cls_004"> in a</span></div>
<div style="position:absolute;left:5.00px;top:711.00px" class="cls_004"><span class="cls_004">separate project, or other referenced assembly, we would merge the file using the following</span></div>
<div style="position:absolute;left:5.00px;top:729.00px" class="cls_004"><span class="cls_004">path.</span></div>
<div style="position:absolute;left:52.98px;top:752.25px" class="cls_007"><span class="cls_007"><ResourceDictionary</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:161202px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background203.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:3.00px" class="cls_007"><span class="cls_007">Source="pack://application:,,,/CompanyName.ApplicationName.Resource</span></div>
<div style="position:absolute;left:52.98px;top:16.50px" class="cls_007"><span class="cls_007">s;</span></div>
<div style="position:absolute;left:67.97px;top:30.00px" class="cls_007"><span class="cls_007">component/Styles/Control Styles.xaml" /></span></div>
<div style="position:absolute;left:5.00px;top:50.25px" class="cls_004"><span class="cls_004">When merging resource files, it is important to understand how naming conflicts will be</span></div>
<div style="position:absolute;left:5.00px;top:68.25px" class="cls_004"><span class="cls_004">resolved. Although the </span><span class="cls_007">x:Key</span><span class="cls_004"> directives that we set on our resources must each be unique</span></div>
<div style="position:absolute;left:5.00px;top:86.25px" class="cls_004"><span class="cls_004">within their declared resource dictionary, it is perfectly legal to have duplicated key values</span></div>
<div style="position:absolute;left:5.00px;top:104.25px" class="cls_004"><span class="cls_004">within separate resource files. As such, there is an order of priority that will be followed in</span></div>
<div style="position:absolute;left:5.00px;top:122.25px" class="cls_004"><span class="cls_004">these cases. Let's see an example.</span></div>
<div style="position:absolute;left:5.00px;top:140.25px" class="cls_004"><span class="cls_004">Imagine that we have the aforementioned referenced resource file in a separate project and</span></div>
<div style="position:absolute;left:5.00px;top:158.25px" class="cls_004"><span class="cls_004">in that file, we have this resource.</span></div>
<div style="position:absolute;left:52.98px;top:181.50px" class="cls_007"><span class="cls_007"><SolidColorBrush x:Key="Brush" Color="Red" /></span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">Note that we would need to add a reference to the </span><span class="cls_007">System.Xaml</span><span class="cls_004"> assembly in that project in</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">order to avoid errors. Now imagine that we also have the locally declared </span><span class="cls_007">Default</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_007"><span class="cls_007">Styles.xaml</span><span class="cls_004"> resource file that was referenced in the previous example and in that file, we</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">have this resource.</span></div>
<div style="position:absolute;left:52.98px;top:279.00px" class="cls_007"><span class="cls_007"><SolidColorBrush x:Key="Brush" Color="Blue" /></span></div>
<div style="position:absolute;left:5.00px;top:299.25px" class="cls_004"><span class="cls_004">Let's add a </span><span class="cls_007">Default Styles 2.xaml</span><span class="cls_004"> resource file with this resource in it.</span></div>
<div style="position:absolute;left:52.98px;top:322.50px" class="cls_007"><span class="cls_007"><SolidColorBrush x:Key="Brush" Color="Orange" /></span></div>
<div style="position:absolute;left:5.00px;top:342.75px" class="cls_004"><span class="cls_004">Now, let's say that we merge all of these resource files and add this additional resource in</span></div>
<div style="position:absolute;left:5.00px;top:360.75px" class="cls_004"><span class="cls_004">our application resource file.</span></div>
<div style="position:absolute;left:52.98px;top:384.00px" class="cls_007"><span class="cls_007"><Application.Resources></span></div>
<div style="position:absolute;left:67.97px;top:397.50px" class="cls_007"><span class="cls_007"><ResourceDictionary></span></div>
<div style="position:absolute;left:82.97px;top:411.00px" class="cls_007"><span class="cls_007"><ResourceDictionary.MergedDictionaries></span></div>
<div style="position:absolute;left:97.96px;top:424.50px" class="cls_007"><span class="cls_007"><ResourceDictionary Source="Default Styles.xaml" /></span></div>
<div style="position:absolute;left:97.96px;top:438.00px" class="cls_007"><span class="cls_007"><ResourceDictionary Source="Default Styles 2.xaml" /></span></div>
<div style="position:absolute;left:97.96px;top:451.50px" class="cls_007"><span class="cls_007"><ResourceDictionary Source="pack://application:,,,/</span></div>
<div style="position:absolute;left:112.96px;top:465.00px" class="cls_007"><span class="cls_007">CompanyName.ApplicationName.Resources;</span></div>
<div style="position:absolute;left:112.96px;top:478.50px" class="cls_007"><span class="cls_007">component/Styles/Control Styles.xaml" /></span></div>
<div style="position:absolute;left:82.97px;top:492.00px" class="cls_007"><span class="cls_007"></ResourceDictionary.MergedDictionaries></span></div>
<div style="position:absolute;left:82.97px;top:505.50px" class="cls_007"><span class="cls_007"><SolidColorBrush x:Key="Brush" Color="Green" /></span></div>
<div style="position:absolute;left:67.97px;top:532.50px" class="cls_007"><span class="cls_007"></ResourceDictionary></span></div>
<div style="position:absolute;left:52.98px;top:546.00px" class="cls_007"><span class="cls_007"></Application.Resources></span></div>
<div style="position:absolute;left:5.00px;top:566.25px" class="cls_004"><span class="cls_004">Finally, let's imagine that we have this in the XAML of one of our Views:</span></div>
<div style="position:absolute;left:52.98px;top:589.50px" class="cls_007"><span class="cls_007"><Button Content="Go"></span></div>
<div style="position:absolute;left:67.97px;top:603.00px" class="cls_007"><span class="cls_007"><Button.Resources></span></div>
<div style="position:absolute;left:82.97px;top:616.50px" class="cls_007"><span class="cls_007"><SolidColorBrush x:Key="Brush" Color="Cyan" /></span></div>
<div style="position:absolute;left:67.97px;top:630.00px" class="cls_007"><span class="cls_007"></Button.Resources></span></div>
<div style="position:absolute;left:67.97px;top:643.50px" class="cls_007"><span class="cls_007"><Button.Style></span></div>
<div style="position:absolute;left:82.97px;top:657.00px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type Button}"></span></div>
<div style="position:absolute;left:97.96px;top:670.50px" class="cls_007"><span class="cls_007"><Setter Property="Foreground" Value="{StaticResource Brush}"</span></div>
<div style="position:absolute;left:52.98px;top:684.00px" class="cls_007"><span class="cls_007">/></span></div>
<div style="position:absolute;left:82.97px;top:697.50px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:67.97px;top:711.00px" class="cls_007"><span class="cls_007"></Button.Style></span></div>
<div style="position:absolute;left:60.48px;top:724.50px" class="cls_007"><span class="cls_007"></Button></span></div>
<div style="position:absolute;left:5.00px;top:744.75px" class="cls_004"><span class="cls_004">Also, let's assume that we have this in the local resources of that file:</span></div>
<div style="position:absolute;left:52.98px;top:768.00px" class="cls_007"><span class="cls_007"><UserControl.Resources></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:162004px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background204.jpg" width=612 height=792></div>
<div style="position:absolute;left:67.97px;top:3.00px" class="cls_007"><span class="cls_007"><SolidColorBrush x:Key="Brush" Color="Purple" /></span></div>
<div style="position:absolute;left:52.98px;top:16.50px" class="cls_007"><span class="cls_007"></UserControl.Resources></span></div>
<div style="position:absolute;left:5.00px;top:36.75px" class="cls_004"><span class="cls_004">When running the application, our button text will be cyan, because the main rule of</span></div>
<div style="position:absolute;left:5.00px;top:54.75px" class="cls_004"><span class="cls_004">resource scope is that the highest priority resource that will be used will always be the most</span></div>
<div style="position:absolute;left:5.00px;top:72.75px" class="cls_004"><span class="cls_004">locally declared resource. If we removed or commented out the local brush declaration, the</span></div>
<div style="position:absolute;left:5.00px;top:90.75px" class="cls_004"><span class="cls_004">button text would then become purple when the application was next run.</span></div>
<div style="position:absolute;left:5.00px;top:108.75px" class="cls_004"><span class="cls_004">If we removed the local purple brush resource from the control's </span><span class="cls_007">Resources</span><span class="cls_004"> section, the</span></div>
<div style="position:absolute;left:5.00px;top:126.75px" class="cls_004"><span class="cls_004">application resources would be searched next in an attempt to resolve the </span><span class="cls_007">Brush</span><span class="cls_004"> resource</span></div>
<div style="position:absolute;left:5.00px;top:144.75px" class="cls_004"><span class="cls_004">key. The next general rule is that the latest declared resource will be resolved. In this way,</span></div>
<div style="position:absolute;left:5.00px;top:162.75px" class="cls_004"><span class="cls_004">the button text would then become green, because of the locally declared resource in the</span></div>
<div style="position:absolute;left:5.00px;top:180.75px" class="cls_007"><span class="cls_007">App.xaml</span><span class="cls_004"> file, which would override the values from the merged dictionaries.</span></div>
<div style="position:absolute;left:5.00px;top:198.75px" class="cls_004"><span class="cls_004">However, if this green brush resource was now removed, an interesting thing will happen.</span></div>
<div style="position:absolute;left:5.00px;top:216.75px" class="cls_004"><span class="cls_004">Given the recently stated rules, we might expect that the button text would then be set to</span></div>
<div style="position:absolute;left:5.00px;top:234.75px" class="cls_004"><span class="cls_004">red by the resource file from the referenced assembly. Instead, it will be set to orange by</span></div>
<div style="position:absolute;left:5.00px;top:252.75px" class="cls_004"><span class="cls_004">the resource in the </span><span class="cls_007">Default Styles 2.xaml</span><span class="cls_004"> file.</span></div>
<div style="position:absolute;left:5.00px;top:270.75px" class="cls_004"><span class="cls_004">This is the result of a combination of the two rules together. The two locally declared</span></div>
<div style="position:absolute;left:5.00px;top:288.75px" class="cls_004"><span class="cls_004">resource files have a higher priority than the resource file from the referenced assembly</span></div>
<div style="position:absolute;left:5.00px;top:306.75px" class="cls_004"><span class="cls_004">because they have been declared more locally than it. The second of the two locally</span></div>
<div style="position:absolute;left:5.00px;top:324.75px" class="cls_004"><span class="cls_004">declared resource files takes precedence over the first because it was declared after the</span></div>
<div style="position:absolute;left:5.00px;top:342.75px" class="cls_004"><span class="cls_004">first.</span></div>
<div style="position:absolute;left:5.00px;top:360.75px" class="cls_004"><span class="cls_004">If we removed the reference to the second of the locally declared resource files, the text</span></div>
<div style="position:absolute;left:5.00px;top:378.75px" class="cls_004"><span class="cls_004">would then be set to blue by the resource in the </span><span class="cls_007">Default Styles.xaml</span><span class="cls_004"> file. If we then</span></div>
<div style="position:absolute;left:5.00px;top:396.75px" class="cls_004"><span class="cls_004">removed the reference to this file, we would finally see the red button text that would be set</span></div>
<div style="position:absolute;left:5.00px;top:414.75px" class="cls_004"><span class="cls_004">by the </span><span class="cls_007">Control Styles.xaml</span><span class="cls_004"> file from the referenced assembly.</span></div>
<div style="position:absolute;left:5.00px;top:432.01px" class="cls_011"><span class="cls_011">Triggering changes</span></div>
<div style="position:absolute;left:5.00px;top:462.00px" class="cls_004"><span class="cls_004">In WPF, we have a number of </span><span class="cls_007">Trigger</span><span class="cls_004"> classes that enable us to modify controls, albeit</span></div>
<div style="position:absolute;left:5.00px;top:480.00px" class="cls_004"><span class="cls_004">most commonly just temporarily. All of them extend the </span><span class="cls_007">TriggerBase</span><span class="cls_004"> base class and</span></div>
<div style="position:absolute;left:5.00px;top:498.00px" class="cls_004"><span class="cls_004">therefore inherit its </span><span class="cls_007">EnterActions</span><span class="cls_004"> and </span><span class="cls_007">ExitActions</span><span class="cls_004"> properties. These two properties enable</span></div>
<div style="position:absolute;left:5.00px;top:516.00px" class="cls_004"><span class="cls_004">us to specify one or more </span><span class="cls_007">TriggerAction</span><span class="cls_004"> objects to apply when the trigger becomes active</span></div>
<div style="position:absolute;left:5.00px;top:534.00px" class="cls_004"><span class="cls_004">and/or inactive respectively.</span></div>
<div style="position:absolute;left:5.00px;top:552.00px" class="cls_004"><span class="cls_004">While most trigger types also contain a </span><span class="cls_007">Setters</span><span class="cls_004"> property that we can use to define one or</span></div>
<div style="position:absolute;left:5.00px;top:570.00px" class="cls_004"><span class="cls_004">more property setters that should occur when a certain condition is met, the </span><span class="cls_007">EventTrigger</span></div>
<div style="position:absolute;left:5.00px;top:588.00px" class="cls_004"><span class="cls_004">class does not. Instead, it provides an </span><span class="cls_007">Actions</span><span class="cls_004"> property that enables us to set one or more</span></div>
<div style="position:absolute;left:5.00px;top:606.00px" class="cls_007"><span class="cls_007">TriggerAction</span><span class="cls_004"> objects to be applied when the trigger becomes active.</span></div>
<div style="position:absolute;left:5.00px;top:624.00px" class="cls_004"><span class="cls_004">Furthermore, unlike the other triggers, the </span><span class="cls_007">EventTrigger</span><span class="cls_004"> class has no concept of state</span></div>
<div style="position:absolute;left:5.00px;top:642.00px" class="cls_004"><span class="cls_004">termination. This means that the action applied by the </span><span class="cls_007">EventTrigger</span><span class="cls_004"> will not be undone</span></div>
<div style="position:absolute;left:5.00px;top:660.00px" class="cls_004"><span class="cls_004">when the triggering condition is no longer true. If you hadn't already guessed this, the</span></div>
<div style="position:absolute;left:5.00px;top:678.00px" class="cls_004"><span class="cls_004">conditions that trigger the </span><span class="cls_007">EventTrigger</span><span class="cls_004"> instances are events, or </span><span class="cls_007">RoutedEvent</span><span class="cls_004"> objects more</span></div>
<div style="position:absolute;left:5.00px;top:696.00px" class="cls_004"><span class="cls_004">specifically. Let's investigate this type of trigger first with a simple example that we saw in</span></div>
<div style="position:absolute;left:5.00px;top:714.00px" class="cls_004"><span class="cls_004">the previous chapter.</span></div>
<div style="position:absolute;left:52.98px;top:737.25px" class="cls_007"><span class="cls_007"><Rectangle Width="300" Height="300" Fill="Orange"></span></div>
<div style="position:absolute;left:67.97px;top:750.75px" class="cls_007"><span class="cls_007"><Rectangle.Triggers></span></div>
<div style="position:absolute;left:82.97px;top:764.25px" class="cls_007"><span class="cls_007"><EventTrigger RoutedEvent="Loaded"></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:162806px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background205.jpg" width=612 height=792></div>
<div style="position:absolute;left:97.96px;top:3.00px" class="cls_007"><span class="cls_007"><BeginStoryboard></span></div>
<div style="position:absolute;left:112.96px;top:16.50px" class="cls_007"><span class="cls_007"><Storyboard Storyboard.TargetProperty="Width"></span></div>
<div style="position:absolute;left:127.95px;top:30.00px" class="cls_007"><span class="cls_007"><DoubleAnimation Duration="0:0:1" To="50"</span></div>
<div style="position:absolute;left:52.98px;top:43.50px" class="cls_007"><span class="cls_007">AutoReverse="True"</span></div>
<div style="position:absolute;left:142.94px;top:57.00px" class="cls_007"><span class="cls_007">RepeatBehavior="Forever" /></span></div>
<div style="position:absolute;left:112.96px;top:70.50px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:97.96px;top:84.00px" class="cls_007"><span class="cls_007"></BeginStoryboard></span></div>
<div style="position:absolute;left:82.97px;top:97.50px" class="cls_007"><span class="cls_007"></EventTrigger></span></div>
<div style="position:absolute;left:67.97px;top:111.00px" class="cls_007"><span class="cls_007"></Rectangle.Triggers></span></div>
<div style="position:absolute;left:52.98px;top:124.50px" class="cls_007"><span class="cls_007"></Rectangle></span></div>
<div style="position:absolute;left:5.00px;top:144.75px" class="cls_004"><span class="cls_004">In this example, the trigger condition is met when the </span><span class="cls_007">FrameworkElement.Loaded</span><span class="cls_004"> event is</span></div>
<div style="position:absolute;left:5.00px;top:162.75px" class="cls_004"><span class="cls_004">raised. The action that is applied is the starting of the declared animation. Note that the</span></div>
<div style="position:absolute;left:5.00px;top:180.75px" class="cls_007"><span class="cls_007">BeginStoryboard</span><span class="cls_004"> class actually extends the </span><span class="cls_007">TriggerAction</span><span class="cls_004"> class and this explains how we</span></div>
<div style="position:absolute;left:5.00px;top:198.75px" class="cls_004"><span class="cls_004">are able to declare it within the trigger. This action will be implicitly added into the</span></div>
<div style="position:absolute;left:5.00px;top:216.75px" class="cls_007"><span class="cls_007">TriggerActionCollection</span><span class="cls_004"> of the </span><span class="cls_007">EventTrigger</span><span class="cls_004"> object, although we could have explicitly set</span></div>
<div style="position:absolute;left:5.00px;top:234.75px" class="cls_004"><span class="cls_004">it as follows:</span></div>
<div style="position:absolute;left:52.98px;top:258.00px" class="cls_007"><span class="cls_007"><EventTrigger RoutedEvent="Loaded"></span></div>
<div style="position:absolute;left:67.97px;top:271.50px" class="cls_007"><span class="cls_007"><EventTrigger.Actions></span></div>
<div style="position:absolute;left:82.97px;top:285.00px" class="cls_007"><span class="cls_007"><BeginStoryboard></span></div>
<div style="position:absolute;left:97.96px;top:298.50px" class="cls_007"><span class="cls_007"><Storyboard Storyboard.TargetProperty="Width"></span></div>
<div style="position:absolute;left:112.96px;top:312.00px" class="cls_007"><span class="cls_007"><DoubleAnimation Duration="0:0:1" To="50"</span></div>
<div style="position:absolute;left:52.98px;top:325.50px" class="cls_007"><span class="cls_007">AutoReverse="True"</span></div>
<div style="position:absolute;left:127.95px;top:339.00px" class="cls_007"><span class="cls_007">RepeatBehavior="Forever" /></span></div>
<div style="position:absolute;left:97.96px;top:352.50px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:82.97px;top:366.00px" class="cls_007"><span class="cls_007"></BeginStoryboard></span></div>
<div style="position:absolute;left:67.97px;top:379.50px" class="cls_007"><span class="cls_007"></EventTrigger.Actions></span></div>
<div style="position:absolute;left:52.98px;top:393.00px" class="cls_007"><span class="cls_007"></EventTrigger></span></div>
<div style="position:absolute;left:5.00px;top:413.25px" class="cls_004"><span class="cls_004">In addition to the </span><span class="cls_007">EventTrigger</span><span class="cls_004"> class, there are also </span><span class="cls_007">Trigger</span><span class="cls_004">, </span><span class="cls_007">DataTrigger</span><span class="cls_004">, </span><span class="cls_007">MultiTrigger</span></div>
<div style="position:absolute;left:5.00px;top:431.25px" class="cls_004"><span class="cls_004">and </span><span class="cls_007">MultiDataTrigger</span><span class="cls_004"> classes that enable us to set properties or control animations when</span></div>
<div style="position:absolute;left:5.00px;top:449.25px" class="cls_004"><span class="cls_004">a certain condition, or multiple conditions in the case of the multi triggers, are met. Each</span></div>
<div style="position:absolute;left:5.00px;top:467.25px" class="cls_004"><span class="cls_004">have their own merits, but apart from the </span><span class="cls_007">EventTrigger</span><span class="cls_004"> class, which can be used in any</span></div>
<div style="position:absolute;left:5.00px;top:485.25px" class="cls_004"><span class="cls_004">trigger collection, there are some restrictions on where we can use them.</span></div>
<div style="position:absolute;left:5.00px;top:503.25px" class="cls_004"><span class="cls_004">Each control that extends the </span><span class="cls_007">FrameworkElement</span><span class="cls_004"> class has a </span><span class="cls_007">Triggers</span><span class="cls_004"> property of type</span></div>
<div style="position:absolute;left:5.00px;top:521.25px" class="cls_007"><span class="cls_007">TriggerCollection</span><span class="cls_004">, that enable us to specify our triggers. However, if you've ever tried to</span></div>
<div style="position:absolute;left:5.00px;top:539.25px" class="cls_004"><span class="cls_004">declare a trigger there, then you're probably aware that we are only allowed to define</span></div>
<div style="position:absolute;left:5.00px;top:557.25px" class="cls_004"><span class="cls_004">triggers of type </span><span class="cls_007">EventTrigger</span><span class="cls_004"> there.</span></div>
<div style="position:absolute;left:5.00px;top:575.25px" class="cls_004"><span class="cls_004">However, there are further trigger collections that we can use to declare our other types of</span></div>
<div style="position:absolute;left:5.00px;top:593.25px" class="cls_004"><span class="cls_004">triggers. When defining a </span><span class="cls_007">ControlTemplate</span><span class="cls_004">, we have access to the</span></div>
<div style="position:absolute;left:5.00px;top:611.25px" class="cls_007"><span class="cls_007">ControlTemplate.Triggers</span><span class="cls_004"> collection. For all other requirements, we can declare our other</span></div>
<div style="position:absolute;left:5.00px;top:629.25px" class="cls_004"><span class="cls_004">triggers in the </span><span class="cls_007">Style.Triggers</span><span class="cls_004"> collection. Remember that triggers defined in styles have a</span></div>
<div style="position:absolute;left:5.00px;top:647.25px" class="cls_004"><span class="cls_004">higher priority than those declared in templates.</span></div>
<div style="position:absolute;left:5.00px;top:665.25px" class="cls_004"><span class="cls_004">Let's now take a look at the remaining types of triggers and what they can do for us. We</span></div>
<div style="position:absolute;left:5.00px;top:683.25px" class="cls_004"><span class="cls_004">start with the most simple, the </span><span class="cls_007">Trigger</span><span class="cls_004"> class. Note that anything that the property trigger</span></div>
<div style="position:absolute;left:5.00px;top:701.25px" class="cls_004"><span class="cls_004">can do, the </span><span class="cls_007">DataTrigger</span><span class="cls_004"> class can also do. However, the property trigger syntax is simpler</span></div>
<div style="position:absolute;left:5.00px;top:719.25px" class="cls_004"><span class="cls_004">and does not involve data binding and so it is more efficient.</span></div>
<div style="position:absolute;left:5.00px;top:737.25px" class="cls_004"><span class="cls_004">There are however, a few requirements to using a property trigger and they are as follows.</span></div>
<div style="position:absolute;left:5.00px;top:755.25px" class="cls_004"><span class="cls_004">The relevant property must be a Dependency Property. Unlike the </span><span class="cls_007">EventTrigger</span><span class="cls_004"> class, the</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:163608px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background206.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">other triggers do not specify actions to be applied when the trigger condition is met, but</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">property setters instead.</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">We are able to specify one or more </span><span class="cls_007">Setter</span><span class="cls_004"> objects within each </span><span class="cls_007">Trigger</span><span class="cls_004"> object and they will</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">also be implicitly added to the trigger's </span><span class="cls_007">Setters</span><span class="cls_004"> property collection if we do not explicitly</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">specify it. Note that also unlike the </span><span class="cls_007">EventTrigger</span><span class="cls_004"> class, all other triggers will return the</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">original property value when the trigger condition is no longer satisfied. Let's look at a</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">simple example:</span></div>
<div style="position:absolute;left:52.98px;top:135.00px" class="cls_007"><span class="cls_007"><Button Content="Go"></span></div>
<div style="position:absolute;left:67.97px;top:148.50px" class="cls_007"><span class="cls_007"><Button.Style></span></div>
<div style="position:absolute;left:82.97px;top:162.00px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type Button}"></span></div>
<div style="position:absolute;left:97.96px;top:175.50px" class="cls_007"><span class="cls_007"><Setter Property="Foreground" Value="Black" /></span></div>
<div style="position:absolute;left:97.96px;top:189.00px" class="cls_007"><span class="cls_007"><Style.Triggers></span></div>
<div style="position:absolute;left:112.96px;top:202.50px" class="cls_007"><span class="cls_007"><Trigger Property="IsMouseOver" Value="True"></span></div>
<div style="position:absolute;left:127.95px;top:216.00px" class="cls_007"><span class="cls_007"><Setter Property="Foreground" Value="Red" /></span></div>
<div style="position:absolute;left:112.96px;top:229.50px" class="cls_007"><span class="cls_007"></Trigger></span></div>
<div style="position:absolute;left:97.96px;top:243.00px" class="cls_007"><span class="cls_007"></Style.Triggers></span></div>
<div style="position:absolute;left:82.97px;top:256.50px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:67.97px;top:270.00px" class="cls_007"><span class="cls_007"></Button.Style></span></div>
<div style="position:absolute;left:52.98px;top:283.50px" class="cls_007"><span class="cls_007"></Button></span></div>
<div style="position:absolute;left:5.00px;top:303.75px" class="cls_004"><span class="cls_004">Here we have a button that will change the color of its text when the user's mouse is over it.</span></div>
<div style="position:absolute;left:5.00px;top:321.75px" class="cls_004"><span class="cls_004">Unlike the </span><span class="cls_007">EventTrigger</span><span class="cls_004"> however, it's text color will return to its previously set color when</span></div>
<div style="position:absolute;left:5.00px;top:339.75px" class="cls_004"><span class="cls_004">the mouse is no longer over the button. Note also that property triggers use the properties</span></div>
<div style="position:absolute;left:5.00px;top:357.75px" class="cls_004"><span class="cls_004">of the controls that they are declared in for their conditions, as they have no way of</span></div>
<div style="position:absolute;left:5.00px;top:375.75px" class="cls_004"><span class="cls_004">specifying any other target.</span></div>
<div style="position:absolute;left:5.00px;top:393.75px" class="cls_004"><span class="cls_004">As previously mentioned, the </span><span class="cls_007">DataTrigger</span><span class="cls_004"> class can also perform this same binding. Let's</span></div>
<div style="position:absolute;left:5.00px;top:411.75px" class="cls_004"><span class="cls_004">see what that might look like:</span></div>
<div style="position:absolute;left:52.98px;top:435.00px" class="cls_007"><span class="cls_007"><Button Content="Go"></span></div>
<div style="position:absolute;left:67.97px;top:448.50px" class="cls_007"><span class="cls_007"><Button.Style></span></div>
<div style="position:absolute;left:82.97px;top:462.00px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type Button}"></span></div>
<div style="position:absolute;left:97.96px;top:475.50px" class="cls_007"><span class="cls_007"><Setter Property="Foreground" Value="Black" /></span></div>
<div style="position:absolute;left:97.96px;top:489.00px" class="cls_007"><span class="cls_007"><Style.Triggers></span></div>
<div style="position:absolute;left:112.96px;top:502.50px" class="cls_007"><span class="cls_007"><DataTrigger Binding="{Binding IsMouseOver,</span></div>
<div style="position:absolute;left:127.95px;top:516.00px" class="cls_007"><span class="cls_007">RelativeSource={RelativeSource Self}}" Value="True"></span></div>
<div style="position:absolute;left:127.95px;top:529.50px" class="cls_007"><span class="cls_007"><Setter Property="Foreground" Value="Red" /></span></div>
<div style="position:absolute;left:112.96px;top:543.00px" class="cls_007"><span class="cls_007"></DataTrigger></span></div>
<div style="position:absolute;left:97.96px;top:556.50px" class="cls_007"><span class="cls_007"></Style.Triggers></span></div>
<div style="position:absolute;left:82.97px;top:570.00px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:67.97px;top:583.50px" class="cls_007"><span class="cls_007"></Button.Style></span></div>
<div style="position:absolute;left:52.98px;top:597.00px" class="cls_007"><span class="cls_007"></Button></span></div>
<div style="position:absolute;left:5.00px;top:617.25px" class="cls_004"><span class="cls_004">As you can see, when using a </span><span class="cls_007">DataTrigger</span><span class="cls_004">, instead of setting the </span><span class="cls_007">Property</span><span class="cls_004"> property of the</span></div>
<div style="position:absolute;left:5.00px;top:635.25px" class="cls_007"><span class="cls_007">Trigger</span><span class="cls_004"> class, we need to set the </span><span class="cls_007">Binding</span><span class="cls_004"> property instead. In order to achieve the same</span></div>
<div style="position:absolute;left:5.00px;top:653.25px" class="cls_004"><span class="cls_004">functionality as the property trigger, we also need to specify the </span><span class="cls_007">RelativeSource.Self</span></div>
<div style="position:absolute;left:5.00px;top:671.25px" class="cls_004"><span class="cls_004">enumeration member to set the binding source to the control that is declaring the trigger.</span></div>
<div style="position:absolute;left:5.00px;top:689.25px" class="cls_004"><span class="cls_004">The general rule of thumb is that when we are able to use a simple property trigger that</span></div>
<div style="position:absolute;left:5.00px;top:707.25px" class="cls_004"><span class="cls_004">uses a property of the host control in its condition, we should use the </span><span class="cls_007">Trigger</span><span class="cls_004"> class. When</span></div>
<div style="position:absolute;left:5.00px;top:725.25px" class="cls_004"><span class="cls_004">we need to use a property of another control, or a data object in our trigger condition, we</span></div>
<div style="position:absolute;left:5.00px;top:743.25px" class="cls_004"><span class="cls_004">should use a </span><span class="cls_007">DataTrigger</span><span class="cls_004">. Let's look at an interesting practical example now.</span></div>
<div style="position:absolute;left:52.98px;top:766.50px" class="cls_007"><span class="cls_007"><Style x:Key="TextBoxStyle" TargetType="{x:Type TextBox}"></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:164410px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background207.jpg" width=612 height=792></div>
<div style="position:absolute;left:67.97px;top:3.00px" class="cls_007"><span class="cls_007"><Style.Triggers></span></div>
<div style="position:absolute;left:82.97px;top:16.50px" class="cls_007"><span class="cls_007"><DataTrigger Binding="{Binding DataContext.IsEditable,</span></div>
<div style="position:absolute;left:97.96px;top:30.00px" class="cls_007"><span class="cls_007">RelativeSource={RelativeSource AncestorType={x:Type</span></div>
<div style="position:absolute;left:52.98px;top:43.50px" class="cls_007"><span class="cls_007">UserControl}},</span></div>
<div style="position:absolute;left:97.96px;top:57.00px" class="cls_007"><span class="cls_007">FallbackValue=True}" Value="False"></span></div>
<div style="position:absolute;left:97.96px;top:70.50px" class="cls_007"><span class="cls_007"><Setter Property="IsReadOnly" Value="True" /></span></div>
<div style="position:absolute;left:82.97px;top:84.00px" class="cls_007"><span class="cls_007"></DataTrigger></span></div>
<div style="position:absolute;left:67.97px;top:97.50px" class="cls_007"><span class="cls_007"></Style.Triggers></span></div>
<div style="position:absolute;left:52.98px;top:111.00px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:5.00px;top:131.25px" class="cls_004"><span class="cls_004">In this style, we added a </span><span class="cls_007">DataTrigger</span><span class="cls_004"> element that data binds to an </span><span class="cls_007">IsEditable</span><span class="cls_004"> property</span></div>
<div style="position:absolute;left:5.00px;top:149.25px" class="cls_004"><span class="cls_004">that we could declare in a View Model class, that would determine whether the users could</span></div>
<div style="position:absolute;left:5.00px;top:167.25px" class="cls_004"><span class="cls_004">edit the data in the controls on the screen or not. This would assume that the an instance of</span></div>
<div style="position:absolute;left:5.00px;top:185.25px" class="cls_004"><span class="cls_004">the View Model was correctly set as the </span><span class="cls_007">UserControl.DataContext</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:5.00px;top:203.25px" class="cls_004"><span class="cls_004">If the value of the </span><span class="cls_007">IsEditable</span><span class="cls_004"> property was </span><span class="cls_007">false</span><span class="cls_004">, then the </span><span class="cls_007">TextBox.IsReadOnly</span><span class="cls_004"> property</span></div>
<div style="position:absolute;left:5.00px;top:221.25px" class="cls_004"><span class="cls_004">would be set to </span><span class="cls_007">true</span><span class="cls_004"> and the control would become un-editable. Using this technique, we</span></div>
<div style="position:absolute;left:5.00px;top:239.25px" class="cls_004"><span class="cls_004">could make all of the controls in a form editable or un-editable by setting this property from</span></div>
<div style="position:absolute;left:5.00px;top:257.25px" class="cls_004"><span class="cls_004">the View Model.</span></div>
<div style="position:absolute;left:5.00px;top:275.25px" class="cls_004"><span class="cls_004">The triggers that we have looked at so far have all used a single condition to trigger their</span></div>
<div style="position:absolute;left:5.00px;top:293.25px" class="cls_004"><span class="cls_004">actions or property changes. However, there are occasionally situations when we might</span></div>
<div style="position:absolute;left:5.00px;top:311.25px" class="cls_004"><span class="cls_004">need more than a single condition to trigger our property changes. For example, in one</span></div>
<div style="position:absolute;left:5.00px;top:329.25px" class="cls_004"><span class="cls_004">situation, we might want one particular style, and in another situation, we might want a</span></div>
<div style="position:absolute;left:5.00px;top:347.25px" class="cls_004"><span class="cls_004">different look. Let's see an example:</span></div>
<div style="position:absolute;left:52.98px;top:370.50px" class="cls_007"><span class="cls_007"><Style x:Key="ButtonStyle" TargetType="{x:Type Button}"></span></div>
<div style="position:absolute;left:67.97px;top:384.00px" class="cls_007"><span class="cls_007"><Setter Property="Foreground" Value="Black" /></span></div>
<div style="position:absolute;left:67.97px;top:397.50px" class="cls_007"><span class="cls_007"><Style.Triggers></span></div>
<div style="position:absolute;left:82.97px;top:411.00px" class="cls_007"><span class="cls_007"><Trigger Property="IsMouseOver" Value="True"></span></div>
<div style="position:absolute;left:97.96px;top:424.50px" class="cls_007"><span class="cls_007"><Setter Property="Foreground" Value="Red" /></span></div>
<div style="position:absolute;left:82.97px;top:438.00px" class="cls_007"><span class="cls_007"></Trigger></span></div>
<div style="position:absolute;left:82.97px;top:451.50px" class="cls_007"><span class="cls_007"><MultiTrigger></span></div>
<div style="position:absolute;left:97.96px;top:465.00px" class="cls_007"><span class="cls_007"><MultiTrigger.Conditions></span></div>
<div style="position:absolute;left:112.96px;top:478.50px" class="cls_007"><span class="cls_007"><Condition Property="IsFocused" Value="True" /></span></div>
<div style="position:absolute;left:112.96px;top:492.00px" class="cls_007"><span class="cls_007"><Condition Property="IsMouseOver" Value="True" /></span></div>
<div style="position:absolute;left:97.96px;top:505.50px" class="cls_007"><span class="cls_007"></MultiTrigger.Conditions></span></div>
<div style="position:absolute;left:97.96px;top:519.00px" class="cls_007"><span class="cls_007"><Setter Property="Foreground" Value="Green" /></span></div>
<div style="position:absolute;left:82.97px;top:532.50px" class="cls_007"><span class="cls_007"></MultiTrigger></span></div>
<div style="position:absolute;left:67.97px;top:546.00px" class="cls_007"><span class="cls_007"></Style.Triggers></span></div>
<div style="position:absolute;left:52.98px;top:559.50px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:5.00px;top:579.75px" class="cls_004"><span class="cls_004">In this example, we have two triggers. The first will change the button text to red when the</span></div>
<div style="position:absolute;left:5.00px;top:597.75px" class="cls_004"><span class="cls_004">mouse is over it. The second will change the button text to green if the mouse is over it and</span></div>
<div style="position:absolute;left:5.00px;top:615.75px" class="cls_004"><span class="cls_004">the button is focused.</span></div>
<div style="position:absolute;left:5.00px;top:633.75px" class="cls_004"><span class="cls_004">Note that we had to declare the two triggers in this order, as triggers are applied from top</span></div>
<div style="position:absolute;left:5.00px;top:651.75px" class="cls_004"><span class="cls_004">to bottom. Had we swapped their order, then the text would never change to green</span></div>
<div style="position:absolute;left:5.00px;top:669.75px" class="cls_004"><span class="cls_004">because the single trigger would always override the value set by the first one.</span></div>
<div style="position:absolute;left:5.00px;top:687.75px" class="cls_004"><span class="cls_004">We can specify as many </span><span class="cls_007">Condition</span><span class="cls_004"> elements as we need within the </span><span class="cls_007">Conditions</span><span class="cls_004"> collection</span></div>
<div style="position:absolute;left:5.00px;top:705.75px" class="cls_004"><span class="cls_004">and as many setters we need within the </span><span class="cls_007">MultiTrigger</span><span class="cls_004"> element itself. However, every</span></div>
<div style="position:absolute;left:5.00px;top:723.75px" class="cls_004"><span class="cls_004">condition must return true in order for the setters or other trigger actions to be applied.</span></div>
<div style="position:absolute;left:5.00px;top:741.75px" class="cls_004"><span class="cls_004">The same can be said for the last trigger type to be introduced here, the</span></div>
<div style="position:absolute;left:5.00px;top:759.75px" class="cls_007"><span class="cls_007">MultiDataTrigger</span><span class="cls_004">. The difference between this trigger and the previous one is the same as</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:165212px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background208.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">that between the property trigger and the data trigger. That is, the data and multi-data</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">triggers have a much wider range of target sources, while triggers and multi triggers only</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">work with properties of the local control.</span></div>
<div style="position:absolute;left:52.98px;top:63.00px" class="cls_007"><span class="cls_007"><StackPanel></span></div>
<div style="position:absolute;left:67.97px;top:76.50px" class="cls_007"><span class="cls_007"><CheckBox Name="ShowErrors" Content="Show Errors"</span></div>
<div style="position:absolute;left:52.98px;top:90.00px" class="cls_007"><span class="cls_007">Margin="0,0,0,10" /></span></div>
<div style="position:absolute;left:67.97px;top:103.50px" class="cls_007"><span class="cls_007"><TextBlock></span></div>
<div style="position:absolute;left:82.97px;top:117.00px" class="cls_007"><span class="cls_007"><TextBlock.Style></span></div>
<div style="position:absolute;left:97.96px;top:130.50px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type TextBlock}"></span></div>
<div style="position:absolute;left:112.96px;top:144.00px" class="cls_007"><span class="cls_007"><Setter Property="Text" Value="No Errors" /></span></div>
<div style="position:absolute;left:112.96px;top:157.50px" class="cls_007"><span class="cls_007"><Style.Triggers></span></div>
<div style="position:absolute;left:127.95px;top:171.00px" class="cls_007"><span class="cls_007"><MultiDataTrigger></span></div>
<div style="position:absolute;left:142.94px;top:184.50px" class="cls_007"><span class="cls_007"><MultiDataTrigger.Conditions></span></div>
<div style="position:absolute;left:157.94px;top:198.00px" class="cls_007"><span class="cls_007"><Condition Binding="{Binding IsValid}" Value="False"</span></div>
<div style="position:absolute;left:52.98px;top:211.50px" class="cls_007"><span class="cls_007">/></span></div>
<div style="position:absolute;left:157.94px;top:225.00px" class="cls_007"><span class="cls_007"><Condition Binding="{Binding IsChecked,</span></div>
<div style="position:absolute;left:172.93px;top:238.50px" class="cls_007"><span class="cls_007">ElementName=ShowErrors}" Value="True" /></span></div>
<div style="position:absolute;left:142.94px;top:252.00px" class="cls_007"><span class="cls_007"></MultiDataTrigger.Conditions></span></div>
<div style="position:absolute;left:142.94px;top:265.50px" class="cls_007"><span class="cls_007"><MultiDataTrigger.Setters></span></div>
<div style="position:absolute;left:157.94px;top:279.00px" class="cls_007"><span class="cls_007"><Setter Property="Text" Value="{Binding ErrorList}"</span></div>
<div style="position:absolute;left:52.98px;top:292.50px" class="cls_007"><span class="cls_007">/></span></div>
<div style="position:absolute;left:142.94px;top:306.00px" class="cls_007"><span class="cls_007"></MultiDataTrigger.Setters></span></div>
<div style="position:absolute;left:127.95px;top:319.50px" class="cls_007"><span class="cls_007"></MultiDataTrigger></span></div>
<div style="position:absolute;left:112.96px;top:333.00px" class="cls_007"><span class="cls_007"></Style.Triggers></span></div>
<div style="position:absolute;left:97.96px;top:346.50px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:82.97px;top:360.00px" class="cls_007"><span class="cls_007"></TextBlock.Style></span></div>
<div style="position:absolute;left:67.97px;top:373.50px" class="cls_007"><span class="cls_007"></TextBlock></span></div>
<div style="position:absolute;left:52.98px;top:400.50px" class="cls_007"><span class="cls_007"></StackPanel></span></div>
<div style="position:absolute;left:5.00px;top:420.75px" class="cls_004"><span class="cls_004">This example demonstrates the wider reach of the </span><span class="cls_007">MultiDataTrigger</span><span class="cls_004"> class, due to its</span></div>
<div style="position:absolute;left:5.00px;top:438.75px" class="cls_004"><span class="cls_004">access to the wide range of binding sources. We have a </span><span class="cls_007">Show Errors</span><span class="cls_004"> checkbox, a </span><span class="cls_007">No</span></div>
<div style="position:absolute;left:5.00px;top:456.75px" class="cls_007"><span class="cls_007">Errors</span><span class="cls_004"> textblock, and let's say some other form fields that are not displayed here. One of</span></div>
<div style="position:absolute;left:5.00px;top:474.75px" class="cls_004"><span class="cls_004">the conditions of this trigger uses the </span><span class="cls_007">ElementName</span><span class="cls_004"> property to set the binding source to this</span></div>
<div style="position:absolute;left:5.00px;top:492.75px" class="cls_004"><span class="cls_004">checkbox and requires it to be checked.</span></div>
<div style="position:absolute;left:5.00px;top:510.75px" class="cls_004"><span class="cls_004">The other condition binds to an </span><span class="cls_007">IsValid</span><span class="cls_004"> property from our View Model that would be set to</span></div>
<div style="position:absolute;left:5.00px;top:528.75px" class="cls_007"><span class="cls_007">true</span><span class="cls_004"> if there were no validation errors. The idea is that when the checkbox is checked and</span></div>
<div style="position:absolute;left:5.00px;top:546.75px" class="cls_004"><span class="cls_004">there are validation errors, the </span><span class="cls_007">Text</span><span class="cls_004"> property of the </span><span class="cls_007">TextBlock</span><span class="cls_004"> element will be data bound</span></div>
<div style="position:absolute;left:5.00px;top:564.75px" class="cls_004"><span class="cls_004">to another View Model property named </span><span class="cls_007">ErrorList</span><span class="cls_004">, that could output a description of the</span></div>
<div style="position:absolute;left:5.00px;top:582.75px" class="cls_004"><span class="cls_004">validation errors.</span></div>
<div style="position:absolute;left:5.00px;top:600.75px" class="cls_004"><span class="cls_004">Also note that in this example, we explicitly declared the </span><span class="cls_007">Setters</span><span class="cls_004"> collection property and</span></div>
<div style="position:absolute;left:5.00px;top:618.75px" class="cls_004"><span class="cls_004">defined our setter within it. However, that is optional and we could have implicitly added the</span></div>
<div style="position:absolute;left:5.00px;top:636.75px" class="cls_004"><span class="cls_004">setter to the same collection without declaring the collection, as shown in the previous</span></div>
<div style="position:absolute;left:5.00px;top:654.75px" class="cls_007"><span class="cls_007">MultiTrigger</span><span class="cls_004"> example.</span></div>
<div style="position:absolute;left:5.00px;top:672.75px" class="cls_004"><span class="cls_004">Before moving onto the next topic, let's take a moment to investigate the </span><span class="cls_007">EnterActions</span><span class="cls_004"> and</span></div>
<div style="position:absolute;left:5.00px;top:690.75px" class="cls_007"><span class="cls_007">ExitActions</span><span class="cls_004"> properties of the </span><span class="cls_007">TriggerBase</span><span class="cls_004"> class, that enable us to specify one or more</span></div>
<div style="position:absolute;left:5.00px;top:708.75px" class="cls_007"><span class="cls_007">TriggerAction</span><span class="cls_004"> objects to apply when the trigger becomes active and/or inactive</span></div>
<div style="position:absolute;left:5.00px;top:726.75px" class="cls_004"><span class="cls_004">respectively.</span></div>
<div style="position:absolute;left:5.00px;top:744.75px" class="cls_004"><span class="cls_004">Note that we cannot specify style setters in these collections, as they are not</span></div>
<div style="position:absolute;left:5.00px;top:762.75px" class="cls_007"><span class="cls_007">TriggerAction</span><span class="cls_004"> objects; setters can be added to the </span><span class="cls_007">Setters</span><span class="cls_004"> collection. Instead, we use</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:166014px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background209.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">these properties to start animations when the trigger becomes active and/or inactive. To do</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">that, we need to add a </span><span class="cls_007">BeginStoryboard</span><span class="cls_004"> element, which does extend the </span><span class="cls_007">TriggerAction</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">class. Let's see an example:</span></div>
<div style="position:absolute;left:52.98px;top:63.00px" class="cls_007"><span class="cls_007"><TextBox Width="200" Height="28"></span></div>
<div style="position:absolute;left:67.97px;top:76.50px" class="cls_007"><span class="cls_007"><TextBox.Style></span></div>
<div style="position:absolute;left:82.97px;top:90.00px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type TextBox}"></span></div>
<div style="position:absolute;left:97.96px;top:103.50px" class="cls_007"><span class="cls_007"><Setter Property="Opacity" Value="0.25" /></span></div>
<div style="position:absolute;left:97.96px;top:117.00px" class="cls_007"><span class="cls_007"><Style.Triggers></span></div>
<div style="position:absolute;left:112.96px;top:130.50px" class="cls_007"><span class="cls_007"><Trigger Property="IsMouseOver" Value="True"></span></div>
<div style="position:absolute;left:127.95px;top:144.00px" class="cls_007"><span class="cls_007"><Trigger.EnterActions></span></div>
<div style="position:absolute;left:142.94px;top:157.50px" class="cls_007"><span class="cls_007"><BeginStoryboard></span></div>
<div style="position:absolute;left:157.94px;top:171.00px" class="cls_007"><span class="cls_007"><Storyboard Storyboard.TargetProperty="Opacity"></span></div>
<div style="position:absolute;left:172.93px;top:184.50px" class="cls_007"><span class="cls_007"><DoubleAnimation Duration="0:0:0.25" To="1.0" /></span></div>
<div style="position:absolute;left:157.94px;top:198.00px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:142.94px;top:211.50px" class="cls_007"><span class="cls_007"></BeginStoryboard></span></div>
<div style="position:absolute;left:127.95px;top:225.00px" class="cls_007"><span class="cls_007"></Trigger.EnterActions></span></div>
<div style="position:absolute;left:127.95px;top:238.50px" class="cls_007"><span class="cls_007"><Trigger.ExitActions></span></div>
<div style="position:absolute;left:142.94px;top:252.00px" class="cls_007"><span class="cls_007"><BeginStoryboard></span></div>
<div style="position:absolute;left:157.94px;top:265.50px" class="cls_007"><span class="cls_007"><Storyboard Storyboard.TargetProperty="Opacity"></span></div>
<div style="position:absolute;left:172.93px;top:279.00px" class="cls_007"><span class="cls_007"><DoubleAnimation Duration="0:0:0.25" To="0.25" /></span></div>
<div style="position:absolute;left:157.94px;top:292.50px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:142.94px;top:306.00px" class="cls_007"><span class="cls_007"></BeginStoryboard></span></div>
<div style="position:absolute;left:127.95px;top:319.50px" class="cls_007"><span class="cls_007"></Trigger.ExitActions></span></div>
<div style="position:absolute;left:112.96px;top:333.00px" class="cls_007"><span class="cls_007"></Trigger></span></div>
<div style="position:absolute;left:97.96px;top:346.50px" class="cls_007"><span class="cls_007"></Style.Triggers></span></div>
<div style="position:absolute;left:82.97px;top:360.00px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:67.97px;top:373.50px" class="cls_007"><span class="cls_007"></TextBox.Style></span></div>
<div style="position:absolute;left:52.98px;top:387.00px" class="cls_007"><span class="cls_007"></TextBox></span></div>
<div style="position:absolute;left:5.00px;top:407.25px" class="cls_004"><span class="cls_004">In this example, the </span><span class="cls_007">Trigger</span><span class="cls_004"> condition relates to the </span><span class="cls_007">IsMouseOver</span><span class="cls_004"> property of the </span><span class="cls_007">TextBox</span></div>
<div style="position:absolute;left:5.00px;top:425.25px" class="cls_004"><span class="cls_004">control. Note that declaring our animations in the </span><span class="cls_007">EnterActions</span><span class="cls_004"> and </span><span class="cls_007">ExitActions</span><span class="cls_004"> properties</span></div>
<div style="position:absolute;left:5.00px;top:443.25px" class="cls_004"><span class="cls_004">when using the </span><span class="cls_007">IsMouseOver</span><span class="cls_004"> property is effectively the same as having two </span><span class="cls_007">EventTrigger</span></div>
<div style="position:absolute;left:5.00px;top:461.25px" class="cls_004"><span class="cls_004">elements, one for the </span><span class="cls_007">MouseEnter</span><span class="cls_004"> event and one for </span><span class="cls_007">MouseLeave</span><span class="cls_004"> event.</span></div>
<div style="position:absolute;left:5.00px;top:479.25px" class="cls_004"><span class="cls_004">In this example, the animation in the </span><span class="cls_007">EnterActions</span><span class="cls_004"> collection will start as the user's mouse</span></div>
<div style="position:absolute;left:5.00px;top:497.25px" class="cls_004"><span class="cls_004">cursor enters the control and the animation in the </span><span class="cls_007">ExitActions</span><span class="cls_004"> collection will start as the</span></div>
<div style="position:absolute;left:5.00px;top:515.25px" class="cls_004"><span class="cls_004">user's mouse cursor leaves the control.</span></div>
<div style="position:absolute;left:5.00px;top:533.25px" class="cls_004"><span class="cls_004">We'll thoroughly cover animations later, in </span><span class="cls_015">Chapter 6</span><span class="cls_004">, </span><span class="cls_006">Mastering Practical Animations</span><span class="cls_004"> but in</span></div>
<div style="position:absolute;left:5.00px;top:552.00px" class="cls_004"><span class="cls_004">short, the animation that starts as the user's mouse cursor enters the control will fade in the</span></div>
<div style="position:absolute;left:5.00px;top:570.00px" class="cls_004"><span class="cls_004">control from being almost transparent, to being opaque.</span></div>
<div style="position:absolute;left:5.00px;top:588.00px" class="cls_004"><span class="cls_004">The other animation will return the </span><span class="cls_007">TextBox</span><span class="cls_004"> control to an almost transparent state when the</span></div>
<div style="position:absolute;left:5.00px;top:606.00px" class="cls_004"><span class="cls_004">user's mouse cursor leaves the control. This creates a nice effect when a mouse is dragged</span></div>
<div style="position:absolute;left:5.00px;top:624.00px" class="cls_004"><span class="cls_004">over a number of controls with this style. Now that we have a good understanding of</span></div>
<div style="position:absolute;left:5.00px;top:642.00px" class="cls_004"><span class="cls_004">triggers, let's move on to find other ways of customizing the standard .NET controls.</span></div>
<div style="position:absolute;left:5.00px;top:659.26px" class="cls_011"><span class="cls_011">Templating controls</span></div>
<div style="position:absolute;left:5.00px;top:689.25px" class="cls_004"><span class="cls_004">While we can greatly vary the look of each control using styles alone, there are occasionally</span></div>
<div style="position:absolute;left:5.00px;top:707.25px" class="cls_004"><span class="cls_004">situations when we need to alter their template to achieve our goal. For example, there is</span></div>
<div style="position:absolute;left:5.00px;top:725.25px" class="cls_004"><span class="cls_004">no direct way to change the background color of a button through styles alone. In these</span></div>
<div style="position:absolute;left:5.00px;top:743.25px" class="cls_004"><span class="cls_004">situations, we need to alter the control's default template.</span></div>
<div style="position:absolute;left:5.00px;top:761.25px" class="cls_004"><span class="cls_004">All UI elements that extend the </span><span class="cls_007">Control</span><span class="cls_004"> class provide access to its </span><span class="cls_007">Template</span><span class="cls_004"> property. This</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:166816px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background210.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">property is of type </span><span class="cls_007">ControlTemplate</span><span class="cls_004"> and enables us to completely replace the originally</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">declared template that defines the normal look of the control. We saw a simple example in</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">the previous chapter, but let's now have a look at another example:</span></div>
<div style="position:absolute;left:52.98px;top:63.00px" class="cls_007"><span class="cls_007"><Button Content="Go" Width="100" HorizontalAlignment="Center"></span></div>
<div style="position:absolute;left:67.97px;top:76.50px" class="cls_007"><span class="cls_007"><Button.Template></span></div>
<div style="position:absolute;left:82.97px;top:90.00px" class="cls_007"><span class="cls_007"><ControlTemplate TargetType="{x:Type Button}"></span></div>
<div style="position:absolute;left:97.96px;top:103.50px" class="cls_007"><span class="cls_007"><Grid></span></div>
<div style="position:absolute;left:112.96px;top:117.00px" class="cls_007"><span class="cls_007"><Ellipse Fill="Orange" Stroke="Black" StrokeThickness="3"</span></div>
<div style="position:absolute;left:127.95px;top:130.50px" class="cls_007"><span class="cls_007">Height="{Binding ActualWidth,</span></div>
<div style="position:absolute;left:127.95px;top:144.00px" class="cls_007"><span class="cls_007">RelativeSource={RelativeSource Self}}" /></span></div>
<div style="position:absolute;left:112.96px;top:157.50px" class="cls_007"><span class="cls_007"><ContentPresenter HorizontalAlignment="Center"</span></div>
<div style="position:absolute;left:127.95px;top:171.00px" class="cls_007"><span class="cls_007">VerticalAlignment="Center" TextElement.FontSize="18"</span></div>
<div style="position:absolute;left:127.95px;top:184.50px" class="cls_007"><span class="cls_007">TextElement.FontWeight="Bold" /></span></div>
<div style="position:absolute;left:97.96px;top:198.00px" class="cls_007"><span class="cls_007"></Grid></span></div>
<div style="position:absolute;left:82.97px;top:211.50px" class="cls_007"><span class="cls_007"></ControlTemplate></span></div>
<div style="position:absolute;left:67.97px;top:225.00px" class="cls_007"><span class="cls_007"></Button.Template></span></div>
<div style="position:absolute;left:52.98px;top:238.50px" class="cls_007"><span class="cls_007"></Button></span></div>
<div style="position:absolute;left:5.00px;top:258.75px" class="cls_004"><span class="cls_004">Here, we have a button that we have altered to look like a circle. It is very basic, as we</span></div>
<div style="position:absolute;left:5.00px;top:276.75px" class="cls_004"><span class="cls_004">have not bothered to define any mouseover or click effects, but it shows that there is</span></div>
<div style="position:absolute;left:5.00px;top:294.75px" class="cls_004"><span class="cls_004">nothing scary about overriding the default template of a control and that it is simple to</span></div>
<div style="position:absolute;left:5.00px;top:312.75px" class="cls_004"><span class="cls_004">achieve.</span></div>
<div style="position:absolute;left:5.00px;top:452.25px" class="cls_004"><span class="cls_004">Note that the </span><span class="cls_007">ContentPresenter</span><span class="cls_004"> element is declared after the </span><span class="cls_007">Ellipse</span><span class="cls_004"> element because the</span></div>
<div style="position:absolute;left:5.00px;top:470.25px" class="cls_004"><span class="cls_004">ellipse is not a content control and cannot have another element set as its content. This</span></div>
<div style="position:absolute;left:5.00px;top:488.25px" class="cls_004"><span class="cls_004">results in the content being drawn on top of the ellipse. A side effect of this is that we</span></div>
<div style="position:absolute;left:5.00px;top:506.25px" class="cls_004"><span class="cls_004">therefore need to add a panel inside the template, to enable us to provide more than a</span></div>
<div style="position:absolute;left:5.00px;top:524.25px" class="cls_004"><span class="cls_004">single piece of content.</span></div>
<div style="position:absolute;left:5.00px;top:542.25px" class="cls_004"><span class="cls_004">Also note that as with styles, we need to specify the </span><span class="cls_007">TargetType</span><span class="cls_004"> property of the template.</span></div>
<div style="position:absolute;left:5.00px;top:560.25px" class="cls_004"><span class="cls_004">To clarify this a little, we need to specify it if the template contains a </span><span class="cls_007">ContentPresenter</span></div>
<div style="position:absolute;left:5.00px;top:578.25px" class="cls_004"><span class="cls_004">element. Note that omitting this value will not raise a compilation error, but the content will</span></div>
<div style="position:absolute;left:5.00px;top:596.25px" class="cls_004"><span class="cls_004">simply not appear in our templated control. It is therefore good practice to always set this</span></div>
<div style="position:absolute;left:5.00px;top:614.25px" class="cls_007"><span class="cls_007">TargetType</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:5.00px;top:632.25px" class="cls_004"><span class="cls_004">However, unlike styles, if we declared a </span><span class="cls_007">ControlTemplate</span><span class="cls_004"> and set its </span><span class="cls_007">TargetType</span><span class="cls_004"> property</span></div>
<div style="position:absolute;left:5.00px;top:650.25px" class="cls_004"><span class="cls_004">in a </span><span class="cls_007">Resources</span><span class="cls_004"> collection without specifying the </span><span class="cls_007">x:Key</span><span class="cls_004"> directive, it will not be implicitly</span></div>
<div style="position:absolute;left:5.00px;top:668.25px" class="cls_004"><span class="cls_004">applied to all buttons in the application. Indeed, we will receive a compilation error.</span></div>
<div style="position:absolute;left:52.98px;top:691.50px" class="cls_009"><span class="cls_009">Each dictionary entry must have an associated key.</span></div>
<div style="position:absolute;left:5.00px;top:712.50px" class="cls_004"><span class="cls_004">Instead, we need to set the </span><span class="cls_007">x:Key</span><span class="cls_004"> directive and explicitly apply the template to the </span><span class="cls_007">Template</span></div>
<div style="position:absolute;left:5.00px;top:730.50px" class="cls_004"><span class="cls_004">property of the control in a style. If we want our template to be applied to every control of</span></div>
<div style="position:absolute;left:5.00px;top:748.50px" class="cls_004"><span class="cls_004">that type then we need to set it in the default style for that type. In this case, we need to</span></div>
<div style="position:absolute;left:5.00px;top:766.50px" class="cls_004"><span class="cls_004">not set the </span><span class="cls_007">x:Key</span><span class="cls_004"> directive of the style, so that it will be implicitly applied.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:167618px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background211.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:6.75px" class="cls_007"><span class="cls_007"><ControlTemplate x:Key="ButtonTemplate" TargetType="{x:Type</span></div>
<div style="position:absolute;left:52.98px;top:20.25px" class="cls_007"><span class="cls_007">Button}"></span></div>
<div style="position:absolute;left:52.98px;top:47.25px" class="cls_007"><span class="cls_007"></ControlTemplate></span></div>
<div style="position:absolute;left:52.98px;top:60.75px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type Button}"></span></div>
<div style="position:absolute;left:67.97px;top:74.25px" class="cls_007"><span class="cls_007"><Setter Property="Template" Value="{StaticResource</span></div>
<div style="position:absolute;left:52.98px;top:87.75px" class="cls_007"><span class="cls_007">ButtonTemplate}" /></span></div>
<div style="position:absolute;left:52.98px;top:101.25px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:5.00px;top:121.50px" class="cls_004"><span class="cls_004">Note that we would not typically hard code property values like we did in this template</span></div>
<div style="position:absolute;left:5.00px;top:139.50px" class="cls_004"><span class="cls_004">example, unless we did not want the users of our framework to be able to set their own</span></div>
<div style="position:absolute;left:5.00px;top:157.50px" class="cls_004"><span class="cls_004">colors on our templated controls. More often than not, we would make proper use of the</span></div>
<div style="position:absolute;left:5.00px;top:175.50px" class="cls_007"><span class="cls_007">TemplateBinding</span><span class="cls_004"> class to apply the values set from outside the control to the inner controls</span></div>
<div style="position:absolute;left:5.00px;top:193.50px" class="cls_004"><span class="cls_004">defined within our template.</span></div>
<div style="position:absolute;left:52.98px;top:216.75px" class="cls_007"><span class="cls_007"><Button Content="Go" Width="100" HorizontalAlignment="Center"</span></div>
<div style="position:absolute;left:67.97px;top:230.25px" class="cls_007"><span class="cls_007">Background="Orange" HorizontalContentAlignment="Center"</span></div>
<div style="position:absolute;left:67.97px;top:243.75px" class="cls_007"><span class="cls_007">VerticalContentAlignment="Center" FontSize="18"></span></div>
<div style="position:absolute;left:67.97px;top:257.25px" class="cls_007"><span class="cls_007"><Button.Template></span></div>
<div style="position:absolute;left:82.97px;top:270.75px" class="cls_007"><span class="cls_007"><ControlTemplate TargetType="{x:Type Button}"></span></div>
<div style="position:absolute;left:97.96px;top:284.25px" class="cls_007"><span class="cls_007"><Grid></span></div>
<div style="position:absolute;left:112.96px;top:297.75px" class="cls_007"><span class="cls_007"><Ellipse Fill="{TemplateBinding Background}"</span></div>
<div style="position:absolute;left:127.95px;top:311.25px" class="cls_007"><span class="cls_007">Stroke="{TemplateBinding Foreground}" StrokeThickness="3"</span></div>
<div style="position:absolute;left:127.95px;top:324.75px" class="cls_007"><span class="cls_007">Height="{Binding ActualWidth,</span></div>
<div style="position:absolute;left:127.95px;top:338.25px" class="cls_007"><span class="cls_007">RelativeSource={RelativeSource Self}}" /></span></div>
<div style="position:absolute;left:112.96px;top:351.75px" class="cls_007"><span class="cls_007"><ContentPresenter HorizontalAlignment="{TemplateBinding</span></div>
<div style="position:absolute;left:127.95px;top:365.25px" class="cls_007"><span class="cls_007">HorizontalContentAlignment}"</span></div>
<div style="position:absolute;left:127.95px;top:378.75px" class="cls_007"><span class="cls_007">VerticalAlignment="{TemplateBinding</span></div>
<div style="position:absolute;left:127.95px;top:392.25px" class="cls_007"><span class="cls_007">VerticalContentAlignment}"</span></div>
<div style="position:absolute;left:127.95px;top:405.75px" class="cls_007"><span class="cls_007">TextElement.FontWeight="{TemplateBinding FontWeight}"</span></div>
<div style="position:absolute;left:127.95px;top:419.25px" class="cls_007"><span class="cls_007">TextElement.FontSize="{TemplateBinding FontSize}" /></span></div>
<div style="position:absolute;left:97.96px;top:432.75px" class="cls_007"><span class="cls_007"></Grid></span></div>
<div style="position:absolute;left:82.97px;top:446.25px" class="cls_007"><span class="cls_007"></ControlTemplate></span></div>
<div style="position:absolute;left:67.97px;top:459.75px" class="cls_007"><span class="cls_007"></Button.Template></span></div>
<div style="position:absolute;left:52.98px;top:473.25px" class="cls_007"><span class="cls_007"></Button></span></div>
<div style="position:absolute;left:5.00px;top:506.25px" class="cls_004"><span class="cls_004">While this example is now far more verbose, it is also more practical and would enable</span></div>
<div style="position:absolute;left:5.00px;top:524.25px" class="cls_004"><span class="cls_004">users to set their own button properties. Setting this template in a default style would make</span></div>
<div style="position:absolute;left:5.00px;top:542.25px" class="cls_004"><span class="cls_004">the templated control far more reusable. Note that now, the hard coded values are made on</span></div>
<div style="position:absolute;left:5.00px;top:560.25px" class="cls_004"><span class="cls_004">the button control itself, with the exception of the </span><span class="cls_007">StrokeThickness</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:5.00px;top:578.25px" class="cls_004"><span class="cls_004">There is no suitable property on the </span><span class="cls_007">Button</span><span class="cls_004"> class that we could use to expose this inner</span></div>
<div style="position:absolute;left:5.00px;top:596.25px" class="cls_004"><span class="cls_004">control property. If this was a problem for us, we could expose the value of that property in</span></div>
<div style="position:absolute;left:5.00px;top:614.25px" class="cls_004"><span class="cls_004">a custom Attached Property and data bind to it on the button as follows:</span></div>
<div style="position:absolute;left:52.98px;top:637.50px" class="cls_007"><span class="cls_007"><Button Attached:ButtonProperties.StrokeThickness="3" ... /></span></div>
<div style="position:absolute;left:5.00px;top:657.75px" class="cls_004"><span class="cls_004">And we could do the following inside the control template:</span></div>
<div style="position:absolute;left:52.98px;top:681.00px" class="cls_007"><span class="cls_007"><Ellipse</span></div>
<div style="position:absolute;left:67.97px;top:694.50px" class="cls_007"><span class="cls_007">Stroke="{Binding (Attached:ButtonProperties.StrokeThickness)}"</span></div>
<div style="position:absolute;left:52.98px;top:708.00px" class="cls_007"><span class="cls_007">... /></span></div>
<div style="position:absolute;left:5.00px;top:728.25px" class="cls_004"><span class="cls_004">However, even though we have improved our template, there are certain elements defined</span></div>
<div style="position:absolute;left:5.00px;top:746.25px" class="cls_004"><span class="cls_004">in the default templates that affect the way their containing controls look, or work. If we</span></div>
<div style="position:absolute;left:5.00px;top:764.25px" class="cls_004"><span class="cls_004">remove these elements, as we have done in the preceding example, we will break that</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:168420px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background212.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">default functionality. For example, our example button no longer has focusing or interaction</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">effects.</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">Sometimes, we may only need to slightly adjust the original template, in which case, we</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">would typically start with the default </span><span class="cls_007">ControlTemplate</span><span class="cls_004"> and then make our slight adjustment</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">to it. If we had done this with our button example and simply replaced the visual aspects,</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">then we could have retained the original interactivity with it.</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">In days gone by, it could be quite difficult to find the default control templates for the various</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">controls. We would previously need to try and track them down on the MSDN website, or</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">use Blend, however now, we can use Visual Studio to provide it for us.</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">In the WPF designer, select the relevant control, or click on it with the mouse in a XAML</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">file. With the relevant control selected, or focused, press the </span><span class="cls_012">F4</span><span class="cls_006"> </span><span class="cls_004">key on your keyboard to</span></div>
<div style="position:absolute;left:5.00px;top:202.50px" class="cls_004"><span class="cls_004">open the </span><span class="cls_005">Properties</span><span class="cls_004"> window. Next, open the </span><span class="cls_005">Miscellaneous</span><span class="cls_004"> category to find the </span><span class="cls_005">Template</span></div>
<div style="position:absolute;left:5.00px;top:221.25px" class="cls_004"><span class="cls_004">property, or type </span><span class="cls_007">Template</span><span class="cls_004"> in the search field at the top of the </span><span class="cls_005">Properties</span><span class="cls_004"> window.</span></div>
<div style="position:absolute;left:5.00px;top:240.00px" class="cls_004"><span class="cls_004">Click on the little square to the right of the </span><span class="cls_005">Template</span><span class="cls_004"> value field and select the </span><span class="cls_005">Convert to</span></div>
<div style="position:absolute;left:5.00px;top:258.75px" class="cls_005"><span class="cls_005">New Resource...</span><span class="cls_004"> item in the template options tooltip. In the popup dialog window that</span></div>
<div style="position:absolute;left:5.00px;top:277.50px" class="cls_004"><span class="cls_004">appears, name the new </span><span class="cls_007">ControlTemplate</span><span class="cls_004"> to be added and decide where you want it to be</span></div>
<div style="position:absolute;left:5.00px;top:295.50px" class="cls_004"><span class="cls_004">defined.</span></div>
<div style="position:absolute;left:5.00px;top:552.75px" class="cls_004"><span class="cls_004">Once you have entered the required details, click the </span><span class="cls_005">OK</span><span class="cls_004"> button to create a copy of the</span></div>
<div style="position:absolute;left:5.00px;top:571.50px" class="cls_004"><span class="cls_004">default template of your selected control in your desired location. As an example, let's take</span></div>
<div style="position:absolute;left:5.00px;top:589.50px" class="cls_004"><span class="cls_004">a look at the default control template of the </span><span class="cls_007">TextBox</span><span class="cls_004"> control.</span></div>
<div style="position:absolute;left:52.98px;top:612.75px" class="cls_007"><span class="cls_007"><ControlTemplate TargetType="{x:Type TextBox}"></span></div>
<div style="position:absolute;left:67.97px;top:626.25px" class="cls_007"><span class="cls_007"><Border Name="border" BorderBrush="{TemplateBinding BorderBrush}"</span></div>
<div style="position:absolute;left:82.97px;top:639.75px" class="cls_007"><span class="cls_007">BorderThickness="{TemplateBinding BorderThickness}"</span></div>
<div style="position:absolute;left:82.97px;top:653.25px" class="cls_007"><span class="cls_007">Background="{TemplateBinding Background}"</span></div>
<div style="position:absolute;left:82.97px;top:666.75px" class="cls_007"><span class="cls_007">SnapsToDevicePixels="True"></span></div>
<div style="position:absolute;left:82.97px;top:680.25px" class="cls_007"><span class="cls_007"><ScrollViewer Name="PART_ContentHost" Focusable="False"</span></div>
<div style="position:absolute;left:97.96px;top:693.75px" class="cls_007"><span class="cls_007">HorizontalScrollBarVisibility="Hidden"</span></div>
<div style="position:absolute;left:97.96px;top:707.25px" class="cls_007"><span class="cls_007">VerticalScrollBarVisibility="Hidden" /></span></div>
<div style="position:absolute;left:67.97px;top:720.75px" class="cls_007"><span class="cls_007"></Border></span></div>
<div style="position:absolute;left:67.97px;top:734.25px" class="cls_007"><span class="cls_007"><ControlTemplate.Triggers></span></div>
<div style="position:absolute;left:82.97px;top:747.75px" class="cls_007"><span class="cls_007"><Trigger Property="IsEnabled" Value="False"></span></div>
<div style="position:absolute;left:97.96px;top:761.25px" class="cls_007"><span class="cls_007"><Setter Property="Opacity" TargetName="border" Value="0.56"</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:169222px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background213.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:3.00px" class="cls_007"><span class="cls_007">/></span></div>
<div style="position:absolute;left:82.97px;top:16.50px" class="cls_007"><span class="cls_007"></Trigger></span></div>
<div style="position:absolute;left:82.97px;top:30.00px" class="cls_007"><span class="cls_007"><Trigger Property="IsMouseOver" Value="True"></span></div>
<div style="position:absolute;left:97.96px;top:43.50px" class="cls_007"><span class="cls_007"><Setter Property="BorderBrush" TargetName="border"</span></div>
<div style="position:absolute;left:112.96px;top:57.00px" class="cls_007"><span class="cls_007">Value="#FF7EB4EA" /></span></div>
<div style="position:absolute;left:82.97px;top:70.50px" class="cls_007"><span class="cls_007"></Trigger></span></div>
<div style="position:absolute;left:82.97px;top:84.00px" class="cls_007"><span class="cls_007"><Trigger Property="IsKeyboardFocused" Value="True"></span></div>
<div style="position:absolute;left:97.96px;top:97.50px" class="cls_007"><span class="cls_007"><Setter Property="BorderBrush" TargetName="border"</span></div>
<div style="position:absolute;left:112.96px;top:111.00px" class="cls_007"><span class="cls_007">Value="#FF569DE5" /></span></div>
<div style="position:absolute;left:82.97px;top:124.50px" class="cls_007"><span class="cls_007"></Trigger></span></div>
<div style="position:absolute;left:67.97px;top:138.00px" class="cls_007"><span class="cls_007"></ControlTemplate.Triggers></span></div>
<div style="position:absolute;left:52.98px;top:151.50px" class="cls_007"><span class="cls_007"></ControlTemplate></span></div>
<div style="position:absolute;left:5.00px;top:184.50px" class="cls_004"><span class="cls_004">As we can see, most of the properties set on the inner controls have been exposed to the</span></div>
<div style="position:absolute;left:5.00px;top:202.50px" class="cls_007"><span class="cls_007">TextBox</span><span class="cls_004"> control through the use of the </span><span class="cls_007">TemplateBinding</span><span class="cls_004"> class. At the end of the template</span></div>
<div style="position:absolute;left:5.00px;top:220.50px" class="cls_004"><span class="cls_004">are the triggers that react to various states, such as focus, mouseover and enabled states.</span></div>
<div style="position:absolute;left:5.00px;top:238.50px" class="cls_004"><span class="cls_004">However, inside the </span><span class="cls_007">Border</span><span class="cls_004"> element, we see a </span><span class="cls_007">ScrollViewer</span><span class="cls_004"> named </span><span class="cls_007">PART_ContentHost</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:256.50px" class="cls_004"><span class="cls_004">The fact that this is named with the </span><span class="cls_007">PART_</span><span class="cls_004"> prefix specifies that this control is required within</span></div>
<div style="position:absolute;left:5.00px;top:274.50px" class="cls_004"><span class="cls_004">this template. All named parts of each UI element will be listed on the </span><span class="cls_006">[ControlType] Styles</span></div>
<div style="position:absolute;left:5.00px;top:293.25px" class="cls_006"><span class="cls_006">and Templates</span><span class="cls_004"> pages of MSDN.</span></div>
<div style="position:absolute;left:5.00px;top:312.00px" class="cls_004"><span class="cls_004">This named part control is required in the textbox because when the textbox is initialized, it</span></div>
<div style="position:absolute;left:5.00px;top:330.00px" class="cls_004"><span class="cls_004">programmatically adds the </span><span class="cls_007">TextBoxView</span><span class="cls_004"> and </span><span class="cls_007">CaretElement</span><span class="cls_004"> objects into the </span><span class="cls_007">ScrollViewer</span></div>
<div style="position:absolute;left:5.00px;top:348.00px" class="cls_004"><span class="cls_004">object and these are the predominant elements that make up the textbox's functionality.</span></div>
<div style="position:absolute;left:5.00px;top:366.00px" class="cls_004"><span class="cls_004">These specially named elements also need to be registered within the declaring class and</span></div>
<div style="position:absolute;left:5.00px;top:384.00px" class="cls_004"><span class="cls_004">we'll find out more about that later in the chapter as well. It is therefore important that we</span></div>
<div style="position:absolute;left:5.00px;top:402.00px" class="cls_004"><span class="cls_004">include these named controls in our custom templates if we want to keep the existing</span></div>
<div style="position:absolute;left:5.00px;top:420.00px" class="cls_004"><span class="cls_004">functionality.</span></div>
<div style="position:absolute;left:5.00px;top:438.00px" class="cls_004"><span class="cls_004">Note that we will not receive any compilation errors, or even trace warnings if we do not</span></div>
<div style="position:absolute;left:5.00px;top:456.00px" class="cls_004"><span class="cls_004">include these named controls and we are free to leave them out if we do not require their</span></div>
<div style="position:absolute;left:5.00px;top:474.00px" class="cls_004"><span class="cls_004">relevant functionality. This following example, while hardly functional, it still perfectly valid.</span></div>
<div style="position:absolute;left:52.98px;top:497.25px" class="cls_007"><span class="cls_007"><TextBox Text="Hidden Text Box"></span></div>
<div style="position:absolute;left:67.97px;top:510.75px" class="cls_007"><span class="cls_007"><TextBox.Template></span></div>
<div style="position:absolute;left:82.97px;top:524.25px" class="cls_007"><span class="cls_007"><ControlTemplate TargetType="{x:Type TextBox}"></span></div>
<div style="position:absolute;left:97.96px;top:537.75px" class="cls_007"><span class="cls_007"><ContentPresenter Content="{TemplateBinding Text}" /></span></div>
<div style="position:absolute;left:82.97px;top:551.25px" class="cls_007"><span class="cls_007"></ControlTemplate></span></div>
<div style="position:absolute;left:67.97px;top:564.75px" class="cls_007"><span class="cls_007"></TextBox.Template></span></div>
<div style="position:absolute;left:52.98px;top:578.25px" class="cls_007"><span class="cls_007"></TextBox></span></div>
<div style="position:absolute;left:5.00px;top:598.50px" class="cls_004"><span class="cls_004">Although this textbox will indeed display the specified text value, it will have no containing</span></div>
<div style="position:absolute;left:5.00px;top:616.50px" class="cls_004"><span class="cls_004">box, like a normal textbox would. What will happen when this template is rendered is that</span></div>
<div style="position:absolute;left:5.00px;top:634.50px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">ContentPresenter</span><span class="cls_004"> element will see a string and default to displaying it in a </span><span class="cls_007">TextBlock</span></div>
<div style="position:absolute;left:5.00px;top:652.50px" class="cls_004"><span class="cls_004">element.</span></div>
<div style="position:absolute;left:5.00px;top:670.50px" class="cls_004"><span class="cls_004">Its </span><span class="cls_007">Text</span><span class="cls_004"> property will still be data bound to the </span><span class="cls_007">Text</span><span class="cls_004"> property of our textbox and so when</span></div>
<div style="position:absolute;left:5.00px;top:688.50px" class="cls_004"><span class="cls_004">focused, it will still act like a textbox and enable us to enter text. Of course, we won't see</span></div>
<div style="position:absolute;left:5.00px;top:706.50px" class="cls_004"><span class="cls_004">when it's focused, because we didn't add any triggers to make that happen and there won't</span></div>
<div style="position:absolute;left:5.00px;top:724.50px" class="cls_004"><span class="cls_004">be a caret as the </span><span class="cls_007">CaretElement</span><span class="cls_004"> object will no longer be added.</span></div>
<div style="position:absolute;left:5.00px;top:742.50px" class="cls_004"><span class="cls_004">Instead, if we simply supply the required named control, even without anything else, we'll</span></div>
<div style="position:absolute;left:5.00px;top:760.50px" class="cls_004"><span class="cls_004">still regain most of the original functionality.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:170024px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background214.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:9.00px" class="cls_007"><span class="cls_007"><TextBox Name="Text" Text="Does this work?"</span></div>
<div style="position:absolute;left:67.97px;top:22.50px" class="cls_007"><span class="cls_007">TextChanged="TextBox_TextChanged"></span></div>
<div style="position:absolute;left:67.97px;top:36.00px" class="cls_007"><span class="cls_007"><TextBox.Template></span></div>
<div style="position:absolute;left:82.97px;top:49.50px" class="cls_007"><span class="cls_007"><ControlTemplate TargetType="{x:Type TextBox}"></span></div>
<div style="position:absolute;left:97.96px;top:63.00px" class="cls_007"><span class="cls_007"><ScrollViewer Margin="0" Name="PART_ContentHost" /></span></div>
<div style="position:absolute;left:82.97px;top:76.50px" class="cls_007"><span class="cls_007"></ControlTemplate></span></div>
<div style="position:absolute;left:67.97px;top:90.00px" class="cls_007"><span class="cls_007"></TextBox.Template></span></div>
<div style="position:absolute;left:52.98px;top:103.50px" class="cls_007"><span class="cls_007"></TextBox></span></div>
<div style="position:absolute;left:5.00px;top:123.75px" class="cls_004"><span class="cls_004">Now when we run our application, we have the textbox caret and text cursor when the</span></div>
<div style="position:absolute;left:5.00px;top:141.75px" class="cls_004"><span class="cls_004">mouse is over the textbox and so we have some of the functionality, but not the look.</span></div>
<div style="position:absolute;left:5.00px;top:159.75px" class="cls_004"><span class="cls_004">However usually, the best option is to keep as much of the original template as we can and</span></div>
<div style="position:absolute;left:5.00px;top:177.75px" class="cls_004"><span class="cls_004">only change the parts that we really need to.</span></div>
<div style="position:absolute;left:5.00px;top:195.01px" class="cls_011"><span class="cls_011">Attaching properties</span></div>
<div style="position:absolute;left:5.00px;top:225.00px" class="cls_004"><span class="cls_004">When using WPF, we have one further tool at our disposal to enable us to manipulate the</span></div>
<div style="position:absolute;left:5.00px;top:243.00px" class="cls_004"><span class="cls_004">built-in controls and avoid the need to create new ones. We are of course, discussing</span></div>
<div style="position:absolute;left:5.00px;top:261.00px" class="cls_004"><span class="cls_004">Attached Properties, so let's extend an example that we started looking at in the previous</span></div>
<div style="position:absolute;left:5.00px;top:279.00px" class="cls_004"><span class="cls_004">chapter.</span></div>
<div style="position:absolute;left:5.00px;top:297.00px" class="cls_004"><span class="cls_004">In order to create a button that will enable us to set a second tooltip message to display</span></div>
<div style="position:absolute;left:5.00px;top:315.00px" class="cls_004"><span class="cls_004">when the control is disabled, we'll need to declare two Attached Properties. One will hold</span></div>
<div style="position:absolute;left:5.00px;top:333.00px" class="cls_004"><span class="cls_004">the disabled tooltip message and the other will be the previously mentioned read-only</span></div>
<div style="position:absolute;left:5.00px;top:351.00px" class="cls_004"><span class="cls_004">property that temporarily holds onto the original tooltip value. Let's look at our full</span></div>
<div style="position:absolute;left:5.00px;top:369.00px" class="cls_007"><span class="cls_007">ButtonProperties</span><span class="cls_004"> class now:</span></div>
<div style="position:absolute;left:52.98px;top:392.25px" class="cls_007"><span class="cls_007">using System.Windows;</span></div>
<div style="position:absolute;left:52.98px;top:405.75px" class="cls_007"><span class="cls_007">using System.Windows.Controls;</span></div>
<div style="position:absolute;left:52.98px;top:432.75px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.Views.Attached</span></div>
<div style="position:absolute;left:52.98px;top:446.25px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:459.75px" class="cls_007"><span class="cls_007">public class ButtonProperties : DependencyObject</span></div>
<div style="position:absolute;left:67.97px;top:473.25px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:486.75px" class="cls_007"><span class="cls_007">private static readonly DependencyPropertyKey</span></div>
<div style="position:absolute;left:97.96px;top:500.25px" class="cls_007"><span class="cls_007">originalToolTipPropertyKey =</span></div>
<div style="position:absolute;left:52.98px;top:527.25px" class="cls_007"><span class="cls_007">DependencyProperty.RegisterAttachedReadOnly("OriginalToolTip",</span></div>
<div style="position:absolute;left:97.96px;top:540.75px" class="cls_007"><span class="cls_007">typeof(string), typeof(ButtonProperties),</span></div>
<div style="position:absolute;left:97.96px;top:554.25px" class="cls_007"><span class="cls_007">new FrameworkPropertyMetadata(default(string)));</span></div>
<div style="position:absolute;left:82.97px;top:581.25px" class="cls_007"><span class="cls_007">public static readonly DependencyProperty</span></div>
<div style="position:absolute;left:52.98px;top:594.75px" class="cls_007"><span class="cls_007">OriginalToolTipProperty =</span></div>
<div style="position:absolute;left:97.96px;top:608.25px" class="cls_007"><span class="cls_007">originalToolTipPropertyKey.DependencyProperty;</span></div>
<div style="position:absolute;left:82.97px;top:635.25px" class="cls_007"><span class="cls_007">public static string GetOriginalToolTip(</span></div>
<div style="position:absolute;left:97.96px;top:648.75px" class="cls_007"><span class="cls_007">DependencyObject dependencyObject)</span></div>
<div style="position:absolute;left:82.97px;top:662.25px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:675.75px" class="cls_007"><span class="cls_007">return</span></div>
<div style="position:absolute;left:112.96px;top:689.25px" class="cls_007"><span class="cls_007">(string)dependencyObject.GetValue(OriginalToolTipProperty);</span></div>
<div style="position:absolute;left:82.97px;top:702.75px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:729.75px" class="cls_007"><span class="cls_007">public static DependencyProperty DisabledToolTipProperty =</span></div>
<div style="position:absolute;left:97.96px;top:743.25px" class="cls_007"><span class="cls_007">DependencyProperty.RegisterAttached("DisabledToolTip",</span></div>
<div style="position:absolute;left:97.96px;top:756.75px" class="cls_007"><span class="cls_007">typeof(string), typeof(ButtonProperties),</span></div>
<div style="position:absolute;left:97.96px;top:770.25px" class="cls_007"><span class="cls_007">new UIPropertyMetadata(string.Empty,</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:170826px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background215.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:3.00px" class="cls_007"><span class="cls_007">OnDisabledToolTipChanged));</span></div>
<div style="position:absolute;left:82.97px;top:30.00px" class="cls_007"><span class="cls_007">public static string GetDisabledToolTip(</span></div>
<div style="position:absolute;left:97.96px;top:43.50px" class="cls_007"><span class="cls_007">DependencyObject dependencyObject)</span></div>
<div style="position:absolute;left:82.97px;top:57.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:70.50px" class="cls_007"><span class="cls_007">return (string)dependencyObject.GetValue(</span></div>
<div style="position:absolute;left:112.96px;top:84.00px" class="cls_007"><span class="cls_007">DisabledToolTipProperty);</span></div>
<div style="position:absolute;left:82.97px;top:97.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:124.50px" class="cls_007"><span class="cls_007">public static void SetDisabledToolTip(</span></div>
<div style="position:absolute;left:97.96px;top:138.00px" class="cls_007"><span class="cls_007">DependencyObject dependencyObject, string value)</span></div>
<div style="position:absolute;left:82.97px;top:151.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:165.00px" class="cls_007"><span class="cls_007">dependencyObject.SetValue(DisabledToolTipProperty, value);</span></div>
<div style="position:absolute;left:82.97px;top:178.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:205.50px" class="cls_007"><span class="cls_007">public static void OnDisabledToolTipChanged(DependencyObject</span></div>
<div style="position:absolute;left:97.96px;top:219.00px" class="cls_007"><span class="cls_007">dependencyObject, DependencyPropertyChangedEventArgs e)</span></div>
<div style="position:absolute;left:82.97px;top:232.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:246.00px" class="cls_007"><span class="cls_007">Button button = dependencyObject as Button;</span></div>
<div style="position:absolute;left:97.96px;top:259.50px" class="cls_007"><span class="cls_007">ToolTipService.SetShowOnDisabled(button, true);</span></div>
<div style="position:absolute;left:97.96px;top:273.00px" class="cls_007"><span class="cls_007">if (e.OldValue == null && e.NewValue != null)</span></div>
<div style="position:absolute;left:112.96px;top:286.50px" class="cls_007"><span class="cls_007">button.IsEnabledChanged += Button_IsEnabledChanged;</span></div>
<div style="position:absolute;left:97.96px;top:300.00px" class="cls_007"><span class="cls_007">else if (e.OldValue != null && e.NewValue == null)</span></div>
<div style="position:absolute;left:112.96px;top:313.50px" class="cls_007"><span class="cls_007">button.IsEnabledChanged -= Button_IsEnabledChanged;</span></div>
<div style="position:absolute;left:82.97px;top:327.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:354.00px" class="cls_007"><span class="cls_007">private static void Button_IsEnabledChanged(object sender,</span></div>
<div style="position:absolute;left:97.96px;top:367.50px" class="cls_007"><span class="cls_007">DependencyPropertyChangedEventArgs e)</span></div>
<div style="position:absolute;left:82.97px;top:381.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:394.50px" class="cls_007"><span class="cls_007">Button button = sender as Button;</span></div>
<div style="position:absolute;left:97.96px;top:408.00px" class="cls_007"><span class="cls_007">if (GetOriginalToolTip(button) == null)</span></div>
<div style="position:absolute;left:112.96px;top:421.50px" class="cls_007"><span class="cls_007">button.SetValue(originalToolTipPropertyKey,</span></div>
<div style="position:absolute;left:112.96px;top:435.00px" class="cls_007"><span class="cls_007">button.ToolTip.ToString());</span></div>
<div style="position:absolute;left:97.96px;top:448.50px" class="cls_007"><span class="cls_007">button.ToolTip = (bool)e.NewValue ?</span></div>
<div style="position:absolute;left:112.96px;top:462.00px" class="cls_007"><span class="cls_007">GetOriginalToolTip(button) : GetDisabledToolTip(button);</span></div>
<div style="position:absolute;left:82.97px;top:475.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:489.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:502.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:535.50px" class="cls_004"><span class="cls_004">As with all Attached Properties, we start with a class that extends the </span><span class="cls_007">DependencyObject</span></div>
<div style="position:absolute;left:5.00px;top:553.50px" class="cls_004"><span class="cls_004">class. In this class, we first declare the read-only </span><span class="cls_007">originalToolTipPropertyKey</span><span class="cls_004"> field using</span></div>
<div style="position:absolute;left:5.00px;top:571.50px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">RegisterAttachedReadOnly</span><span class="cls_004"> method and the </span><span class="cls_007">OriginalToolTipProperty</span><span class="cls_004"> property and its</span></div>
<div style="position:absolute;left:5.00px;top:589.50px" class="cls_004"><span class="cls_004">associated CLR getter.</span></div>
<div style="position:absolute;left:5.00px;top:607.50px" class="cls_004"><span class="cls_004">Next, we use the </span><span class="cls_007">RegisterAttached</span><span class="cls_004"> method to register the </span><span class="cls_007">DisabledToolTip</span><span class="cls_004"> property that</span></div>
<div style="position:absolute;left:5.00px;top:625.50px" class="cls_004"><span class="cls_004">will hold the value of the tooltip to be displayed when the control is disabled. We then see</span></div>
<div style="position:absolute;left:5.00px;top:643.50px" class="cls_004"><span class="cls_004">its CLR getter and setter methods and its all-important </span><span class="cls_007">PropertyChangedCallback</span><span class="cls_004"> handling</span></div>
<div style="position:absolute;left:5.00px;top:661.50px" class="cls_004"><span class="cls_004">method.</span></div>
<div style="position:absolute;left:5.00px;top:679.50px" class="cls_004"><span class="cls_004">In the </span><span class="cls_007">OnDisabledToolTipChanged</span><span class="cls_004"> method, we first cast the </span><span class="cls_007">dependencyObject</span><span class="cls_004"> input</span></div>
<div style="position:absolute;left:5.00px;top:697.50px" class="cls_004"><span class="cls_004">parameter to its actual type of </span><span class="cls_007">Button</span><span class="cls_004">. We then use it to set the</span></div>
<div style="position:absolute;left:5.00px;top:715.50px" class="cls_007"><span class="cls_007">ToolTipService.SetShowOnDisabled</span><span class="cls_004"> Attached Property to </span><span class="cls_007">true</span><span class="cls_004">, which is required because</span></div>
<div style="position:absolute;left:5.00px;top:733.50px" class="cls_004"><span class="cls_004">we want the button's tooltip to be displayed when the button is disabled. The default value</span></div>
<div style="position:absolute;left:5.00px;top:751.50px" class="cls_004"><span class="cls_004">is </span><span class="cls_007">false</span><span class="cls_004">, so our Attached Property would not work without this step.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:171628px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background216.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">Next, we determine whether we need to attach or detach the </span><span class="cls_007">Button_IsEnabledChanged</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">event handling method dependent upon the </span><span class="cls_007">NewValue</span><span class="cls_004"> and </span><span class="cls_007">OldValue</span><span class="cls_004"> property values of the</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_007"><span class="cls_007">DependencyPropertyChangedEventArgs</span><span class="cls_004"> object. If the old value is null, then the property has</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">not been set before and we need to attach the handler and if the new value is null, then we</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">need to detach the handler.</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">In the </span><span class="cls_007">Button_IsEnabledChanged</span><span class="cls_004"> event handling method, we first cast the </span><span class="cls_007">sender</span><span class="cls_004"> input</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">parameter to the </span><span class="cls_007">Button</span><span class="cls_004"> type. We then use it to access the </span><span class="cls_007">OriginalToolTip</span><span class="cls_004"> property and</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">if it is null, we set it with the current value from the control's normal </span><span class="cls_007">ToolTip</span><span class="cls_004"> property. Note</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">that we need to pass the </span><span class="cls_007">originalToolTipPropertyKey</span><span class="cls_004"> field into the </span><span class="cls_007">SetValue</span><span class="cls_004"> method, as it</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">is a read-only property.</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">Finally, we utilize the </span><span class="cls_007">e.NewValue</span><span class="cls_004"> property value to determine whether to set the original</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">tooltip or the disabled tooltip into the control's normal </span><span class="cls_007">ToolTip</span><span class="cls_004"> property. Therefore, if the</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">control is enabled, the </span><span class="cls_007">e.NewValue</span><span class="cls_004"> property value will be </span><span class="cls_007">true</span><span class="cls_004"> and the original tooltip will be</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">returned and if the button is disabled, the disabled tooltip will be displayed. We could use</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">this Attached Property as follows:</span></div>
<div style="position:absolute;left:52.98px;top:279.00px" class="cls_007"><span class="cls_007"><Button Content="Save"</span></div>
<div style="position:absolute;left:52.98px;top:292.50px" class="cls_007"><span class="cls_007">Attached:ButtonProperties.DisabledToolTip="You must</span></div>
<div style="position:absolute;left:67.97px;top:306.00px" class="cls_007"><span class="cls_007">correct validation errors before saving" ToolTip="Saves the user"</span></div>
<div style="position:absolute;left:52.98px;top:319.50px" class="cls_007"><span class="cls_007">/></span></div>
<div style="position:absolute;left:5.00px;top:339.75px" class="cls_004"><span class="cls_004">As can be seen from this simple example, Attached Properties enable us to easily add new</span></div>
<div style="position:absolute;left:5.00px;top:357.75px" class="cls_004"><span class="cls_004">functionality to the existing suite of UI controls. This again highlights how versatile WPF is</span></div>
<div style="position:absolute;left:5.00px;top:375.75px" class="cls_004"><span class="cls_004">and demonstrates that we often have no need to create completely new controls.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:172430px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background217.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_008"><span class="cls_008">Combining controls</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">When we need to arrange a number of existing controls in a particular way, we typically use</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">a </span><span class="cls_007">UserControl</span><span class="cls_004"> object. This is why we normally use this type of control to build our Views.</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">However, when we need to build a reusable control, such as an address control, we tend to</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">separate these from our Views, by declaring them in a </span><span class="cls_007">Controls</span><span class="cls_004"> folder and namespace</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">within our Views project.</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">When declaring these reusable controls, it is customary to define Dependency Properties in</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">the code behind and as long as there is no business-related functionality in the control, it is</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">also ok to use the code behind to handle events. If the control is business-related, then we</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">can use a View Model, as we do with normal Views. Let's take a look at an example of an</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">address control.</span></div>
<div style="position:absolute;left:52.98px;top:225.00px" class="cls_007"><span class="cls_007"><UserControl x:Class=</span></div>
<div style="position:absolute;left:67.97px;top:238.50px" class="cls_007"><span class="cls_007">"CompanyName.ApplicationName.Views.Controls.AddressControl"</span></div>
<div style="position:absolute;left:67.97px;top:252.00px" class="cls_007"><span class="cls_007">xmlns="</span><A HREF="http://schemas.microsoft.com/winfx/2006/xaml/presentation"/">http://schemas.microsoft.com/winfx/2006/xaml/presentation"</A> </div>
<div style="position:absolute;left:67.97px;top:265.50px" class="cls_007"><span class="cls_007">xmlns:x="</span><A HREF="http://schemas.microsoft.com/winfx/2006/xaml"/">http://schemas.microsoft.com/winfx/2006/xaml"</A> </div>
<div style="position:absolute;left:67.97px;top:279.00px" class="cls_007"><span class="cls_007">xmlns:mc="</span><A HREF="http://schemas.openxmlformats.org/markup-/">http://schemas.openxmlformats.org/markup-</A> </div>
<div style="position:absolute;left:52.98px;top:292.50px" class="cls_007"><span class="cls_007">compatibility/2006"</span></div>
<div style="position:absolute;left:67.97px;top:306.00px" class="cls_007"><span class="cls_007">xmlns:d="</span><A HREF="http://schemas.microsoft.com/expression/blend/2008"/">http://schemas.microsoft.com/expression/blend/2008"</A> </div>
<div style="position:absolute;left:67.97px;top:319.50px" class="cls_007"><span class="cls_007">xmlns:Controls=</span></div>
<div style="position:absolute;left:82.97px;top:333.00px" class="cls_007"><span class="cls_007">"clr-namespace:CompanyName.ApplicationName.Views.Controls"</span></div>
<div style="position:absolute;left:67.97px;top:346.50px" class="cls_007"><span class="cls_007">mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"></span></div>
<div style="position:absolute;left:67.97px;top:360.00px" class="cls_007"><span class="cls_007"><Grid></span></div>
<div style="position:absolute;left:82.97px;top:373.50px" class="cls_007"><span class="cls_007"><Grid.ColumnDefinitions></span></div>
<div style="position:absolute;left:97.96px;top:387.00px" class="cls_007"><span class="cls_007"><ColumnDefinition Width="Auto" SharedSizeGroup="Label" /></span></div>
<div style="position:absolute;left:97.96px;top:400.50px" class="cls_007"><span class="cls_007"><ColumnDefinition /></span></div>
<div style="position:absolute;left:82.97px;top:414.00px" class="cls_007"><span class="cls_007"></Grid.ColumnDefinitions></span></div>
<div style="position:absolute;left:82.97px;top:427.50px" class="cls_007"><span class="cls_007"><Grid.RowDefinitions></span></div>
<div style="position:absolute;left:97.96px;top:441.00px" class="cls_007"><span class="cls_007"><RowDefinition Height="Auto" /></span></div>
<div style="position:absolute;left:97.96px;top:454.50px" class="cls_007"><span class="cls_007"><RowDefinition Height="Auto" /></span></div>
<div style="position:absolute;left:97.96px;top:468.00px" class="cls_007"><span class="cls_007"><RowDefinition Height="Auto" /></span></div>
<div style="position:absolute;left:97.96px;top:481.50px" class="cls_007"><span class="cls_007"><RowDefinition Height="Auto" /></span></div>
<div style="position:absolute;left:97.96px;top:495.00px" class="cls_007"><span class="cls_007"><RowDefinition Height="Auto" /></span></div>
<div style="position:absolute;left:82.97px;top:508.50px" class="cls_007"><span class="cls_007"></Grid.RowDefinitions></span></div>
<div style="position:absolute;left:82.97px;top:522.00px" class="cls_007"><span class="cls_007"><TextBlock Text="House/Street" /></span></div>
<div style="position:absolute;left:82.97px;top:535.50px" class="cls_007"><span class="cls_007"><TextBox Grid.Column="1" Text="{Binding Address.HouseAndStreet,</span></div>
<div style="position:absolute;left:97.96px;top:549.00px" class="cls_007"><span class="cls_007">RelativeSource={RelativeSource</span></div>
<div style="position:absolute;left:97.96px;top:562.50px" class="cls_007"><span class="cls_007">AncestorType={x:Type Controls:AddressControl}}}" /></span></div>
<div style="position:absolute;left:82.97px;top:576.00px" class="cls_007"><span class="cls_007"><TextBlock Grid.Row="1" Text="Town" /></span></div>
<div style="position:absolute;left:82.97px;top:589.50px" class="cls_007"><span class="cls_007"><TextBox Grid.Row="1" Grid.Column="1"</span></div>
<div style="position:absolute;left:97.96px;top:603.00px" class="cls_007"><span class="cls_007">Text="{Binding Address.Town, RelativeSource={RelativeSource</span></div>
<div style="position:absolute;left:97.96px;top:616.50px" class="cls_007"><span class="cls_007">AncestorType={x:Type Controls:AddressControl}}}" /></span></div>
<div style="position:absolute;left:82.97px;top:630.00px" class="cls_007"><span class="cls_007"><TextBlock Grid.Row="2" Text="City" /></span></div>
<div style="position:absolute;left:82.97px;top:643.50px" class="cls_007"><span class="cls_007"><TextBox Grid.Row="2" Grid.Column="1"</span></div>
<div style="position:absolute;left:97.96px;top:657.00px" class="cls_007"><span class="cls_007">Text="{Binding Address.City, RelativeSource={RelativeSource</span></div>
<div style="position:absolute;left:97.96px;top:670.50px" class="cls_007"><span class="cls_007">AncestorType={x:Type Controls:AddressControl}}}" /></span></div>
<div style="position:absolute;left:82.97px;top:684.00px" class="cls_007"><span class="cls_007"><TextBlock Grid.Row="3" Text="Post Code" /></span></div>
<div style="position:absolute;left:82.97px;top:697.50px" class="cls_007"><span class="cls_007"><TextBox Grid.Row="3" Grid.Column="1"</span></div>
<div style="position:absolute;left:97.96px;top:711.00px" class="cls_007"><span class="cls_007">Text="{Binding Address.PostCode, RelativeSource=</span></div>
<div style="position:absolute;left:52.98px;top:724.50px" class="cls_007"><span class="cls_007">{RelativeSource</span></div>
<div style="position:absolute;left:97.96px;top:738.00px" class="cls_007"><span class="cls_007">AncestorType={x:Type Controls:AddressControl}}}" /></span></div>
<div style="position:absolute;left:82.97px;top:751.50px" class="cls_007"><span class="cls_007"><TextBlock Grid.Row="4" Text="Country" /></span></div>
<div style="position:absolute;left:82.97px;top:765.00px" class="cls_007"><span class="cls_007"><TextBox Grid.Row="4" Grid.Column="1"</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:173232px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background218.jpg" width=612 height=792></div>
<div style="position:absolute;left:97.96px;top:3.00px" class="cls_007"><span class="cls_007">Text="{Binding Address.Country, RelativeSource=</span></div>
<div style="position:absolute;left:52.98px;top:16.50px" class="cls_007"><span class="cls_007">{RelativeSource</span></div>
<div style="position:absolute;left:97.96px;top:30.00px" class="cls_007"><span class="cls_007">AncestorType={x:Type Controls:AddressControl}}}" /></span></div>
<div style="position:absolute;left:67.97px;top:43.50px" class="cls_007"><span class="cls_007"></Grid></span></div>
<div style="position:absolute;left:52.98px;top:57.00px" class="cls_007"><span class="cls_007"></UserControl></span></div>
<div style="position:absolute;left:5.00px;top:90.00px" class="cls_004"><span class="cls_004">In this example, we declare this class within the </span><span class="cls_007">Controls</span><span class="cls_004"> namespace and set up a XAML</span></div>
<div style="position:absolute;left:5.00px;top:108.00px" class="cls_004"><span class="cls_004">namespace prefix for it. We then see the </span><span class="cls_007">Grid</span><span class="cls_004"> panel that is used to layout the address</span></div>
<div style="position:absolute;left:5.00px;top:126.00px" class="cls_004"><span class="cls_004">controls and notice that the </span><span class="cls_007">SharedSizeGroup</span><span class="cls_004"> property is set on the </span><span class="cls_007">ColumnDefinition</span></div>
<div style="position:absolute;left:5.00px;top:144.00px" class="cls_004"><span class="cls_004">element that defines the label column. This will enable the column sizes within this control to</span></div>
<div style="position:absolute;left:5.00px;top:162.00px" class="cls_004"><span class="cls_004">be shared with externally declared controls.</span></div>
<div style="position:absolute;left:5.00px;top:180.00px" class="cls_004"><span class="cls_004">We then see all of the </span><span class="cls_007">TextBlock</span><span class="cls_004"> and </span><span class="cls_007">TextBox</span><span class="cls_004"> controls that are data bound to the control's</span></div>
<div style="position:absolute;left:5.00px;top:198.00px" class="cls_004"><span class="cls_004">address fields. There's not much to note here except that the data bound properties are all</span></div>
<div style="position:absolute;left:5.00px;top:216.00px" class="cls_004"><span class="cls_004">accessed through a </span><span class="cls_007">RelativeSource</span><span class="cls_004"> binding to an </span><span class="cls_007">Address</span><span class="cls_004"> Dependency Property that is</span></div>
<div style="position:absolute;left:5.00px;top:234.00px" class="cls_004"><span class="cls_004">declared in the code behind file of the </span><span class="cls_007">AddressControl</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:252.00px" class="cls_004"><span class="cls_004">Remember that it's fine to do this when using MVVM as long as we are not encapsulating</span></div>
<div style="position:absolute;left:5.00px;top:270.00px" class="cls_004"><span class="cls_004">any business rules here. Our control merely enables the users to input or add address</span></div>
<div style="position:absolute;left:5.00px;top:288.00px" class="cls_004"><span class="cls_004">information, which will be used by various Views and View Models. Let's see this property</span></div>
<div style="position:absolute;left:5.00px;top:306.00px" class="cls_004"><span class="cls_004">now.</span></div>
<div style="position:absolute;left:52.98px;top:329.25px" class="cls_007"><span class="cls_007">using System.Windows;</span></div>
<div style="position:absolute;left:52.98px;top:342.75px" class="cls_007"><span class="cls_007">using System.Windows.Controls;</span></div>
<div style="position:absolute;left:52.98px;top:356.25px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.DataModels;</span></div>
<div style="position:absolute;left:52.98px;top:383.25px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.Views.Controls</span></div>
<div style="position:absolute;left:52.98px;top:396.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:410.25px" class="cls_007"><span class="cls_007">public partial class AddressControl : UserControl</span></div>
<div style="position:absolute;left:67.97px;top:423.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:437.25px" class="cls_007"><span class="cls_007">public AddressControl()</span></div>
<div style="position:absolute;left:82.97px;top:450.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:464.25px" class="cls_007"><span class="cls_007">InitializeComponent();</span></div>
<div style="position:absolute;left:82.97px;top:477.75px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:504.75px" class="cls_007"><span class="cls_007">public static readonly DependencyProperty AddressProperty =</span></div>
<div style="position:absolute;left:97.96px;top:518.25px" class="cls_007"><span class="cls_007">DependencyProperty.Register(nameof(Address),</span></div>
<div style="position:absolute;left:97.96px;top:531.75px" class="cls_007"><span class="cls_007">typeof(Address), typeof(AddressControl),</span></div>
<div style="position:absolute;left:97.96px;top:545.25px" class="cls_007"><span class="cls_007">new PropertyMetadata(new Address()));</span></div>
<div style="position:absolute;left:82.97px;top:572.25px" class="cls_007"><span class="cls_007">public Address Address</span></div>
<div style="position:absolute;left:82.97px;top:585.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:599.25px" class="cls_007"><span class="cls_007">get { return (Address)GetValue(AddressProperty); }</span></div>
<div style="position:absolute;left:97.96px;top:612.75px" class="cls_007"><span class="cls_007">set { SetValue(AddressProperty, value); }</span></div>
<div style="position:absolute;left:82.97px;top:626.25px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:639.75px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:653.25px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:673.50px" class="cls_004"><span class="cls_004">This is a very simple control with just one Dependency Property. We can see that the</span></div>
<div style="position:absolute;left:5.00px;top:691.50px" class="cls_007"><span class="cls_007">Address</span><span class="cls_004"> property is of type </span><span class="cls_007">Address</span><span class="cls_004">, so let's have a quick look at that class next:</span></div>
<div style="position:absolute;left:52.98px;top:714.75px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.DataModels</span></div>
<div style="position:absolute;left:52.98px;top:728.25px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:741.75px" class="cls_007"><span class="cls_007">public class Address : BaseDataModel</span></div>
<div style="position:absolute;left:67.97px;top:755.25px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:768.75px" class="cls_007"><span class="cls_007">private string houseAndStreet, town, city, postCode, country;</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:174034px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background219.jpg" width=612 height=792></div>
<div style="position:absolute;left:82.97px;top:16.50px" class="cls_007"><span class="cls_007">public string HouseAndStreet</span></div>
<div style="position:absolute;left:82.97px;top:30.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:43.50px" class="cls_007"><span class="cls_007">get { return houseAndStreet; }</span></div>
<div style="position:absolute;left:97.96px;top:57.00px" class="cls_007"><span class="cls_007">set { if (houseAndStreet != value) { houseAndStreet = value;</span></div>
<div style="position:absolute;left:112.96px;top:70.50px" class="cls_007"><span class="cls_007">NotifyPropertyChanged(); } }</span></div>
<div style="position:absolute;left:82.97px;top:84.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:111.00px" class="cls_007"><span class="cls_007">public string Town</span></div>
<div style="position:absolute;left:82.97px;top:124.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:138.00px" class="cls_007"><span class="cls_007">get { return town; }</span></div>
<div style="position:absolute;left:97.96px;top:151.50px" class="cls_007"><span class="cls_007">set { if (town != value) { town = value;</span></div>
<div style="position:absolute;left:52.98px;top:165.00px" class="cls_007"><span class="cls_007">NotifyPropertyChanged(); } }</span></div>
<div style="position:absolute;left:82.97px;top:192.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:219.00px" class="cls_007"><span class="cls_007">public string City</span></div>
<div style="position:absolute;left:82.97px;top:232.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:246.00px" class="cls_007"><span class="cls_007">get { return city; }</span></div>
<div style="position:absolute;left:97.96px;top:259.50px" class="cls_007"><span class="cls_007">set { if (city != value) { city = value;</span></div>
<div style="position:absolute;left:52.98px;top:273.00px" class="cls_007"><span class="cls_007">NotifyPropertyChanged(); } }</span></div>
<div style="position:absolute;left:82.97px;top:300.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:327.00px" class="cls_007"><span class="cls_007">public string PostCode</span></div>
<div style="position:absolute;left:82.97px;top:340.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:354.00px" class="cls_007"><span class="cls_007">get { return postCode; }</span></div>
<div style="position:absolute;left:97.96px;top:367.50px" class="cls_007"><span class="cls_007">set { if (postCode != value) { postCode = value;</span></div>
<div style="position:absolute;left:112.96px;top:381.00px" class="cls_007"><span class="cls_007">NotifyPropertyChanged(); } }</span></div>
<div style="position:absolute;left:82.97px;top:394.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:421.50px" class="cls_007"><span class="cls_007">public string Country</span></div>
<div style="position:absolute;left:82.97px;top:435.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:448.50px" class="cls_007"><span class="cls_007">get { return country; }</span></div>
<div style="position:absolute;left:97.96px;top:462.00px" class="cls_007"><span class="cls_007">set { if (country != value) { country = value;</span></div>
<div style="position:absolute;left:112.96px;top:475.50px" class="cls_007"><span class="cls_007">NotifyPropertyChanged(); } }</span></div>
<div style="position:absolute;left:82.97px;top:489.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:516.00px" class="cls_007"><span class="cls_007">public override string ToString()</span></div>
<div style="position:absolute;left:82.97px;top:529.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:543.00px" class="cls_007"><span class="cls_007">return $"{HouseAndStreet}, {Town}, {City}, {PostCode},</span></div>
<div style="position:absolute;left:52.98px;top:556.50px" class="cls_007"><span class="cls_007">{Country}";</span></div>
<div style="position:absolute;left:82.97px;top:570.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:583.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:597.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:630.00px" class="cls_004"><span class="cls_004">Again, we have a very simple class that is primarily made up from the address related</span></div>
<div style="position:absolute;left:5.00px;top:648.00px" class="cls_004"><span class="cls_004">properties. Note the use of the string interpolation in the overridden </span><span class="cls_007">ToString</span><span class="cls_004"> method to</span></div>
<div style="position:absolute;left:5.00px;top:666.00px" class="cls_004"><span class="cls_004">output a useful display of the class contents. Now we've seen the control, let's take a look</span></div>
<div style="position:absolute;left:5.00px;top:684.00px" class="cls_004"><span class="cls_004">at how we can use it in our application. We can edit a View that we saw earlier, so let's see</span></div>
<div style="position:absolute;left:5.00px;top:702.00px" class="cls_004"><span class="cls_004">the updated </span><span class="cls_007">UserView</span><span class="cls_004"> XAML now.</span></div>
<div style="position:absolute;left:52.98px;top:725.25px" class="cls_007"><span class="cls_007"><Grid TextElement.FontSize="14" Grid.IsSharedSizeScope="True"</span></div>
<div style="position:absolute;left:52.98px;top:738.75px" class="cls_007"><span class="cls_007">Margin="10"></span></div>
<div style="position:absolute;left:67.97px;top:752.25px" class="cls_007"><span class="cls_007"><Grid.Resources></span></div>
<div style="position:absolute;left:82.97px;top:765.75px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type TextBlock}"></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:174836px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background220.jpg" width=612 height=792></div>
<div style="position:absolute;left:97.96px;top:3.00px" class="cls_007"><span class="cls_007"><Setter Property="HorizontalAlignment" Value="Right" /></span></div>
<div style="position:absolute;left:97.96px;top:16.50px" class="cls_007"><span class="cls_007"><Setter Property="VerticalAlignment" Value="Center" /></span></div>
<div style="position:absolute;left:97.96px;top:30.00px" class="cls_007"><span class="cls_007"><Setter Property="Margin" Value="0,0,5,5" /></span></div>
<div style="position:absolute;left:82.97px;top:43.50px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:82.97px;top:57.00px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type TextBox}"></span></div>
<div style="position:absolute;left:97.96px;top:70.50px" class="cls_007"><span class="cls_007"><Setter Property="VerticalAlignment" Value="Center" /></span></div>
<div style="position:absolute;left:97.96px;top:84.00px" class="cls_007"><span class="cls_007"><Setter Property="Margin" Value="0,0,0,5" /></span></div>
<div style="position:absolute;left:82.97px;top:97.50px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:67.97px;top:111.00px" class="cls_007"><span class="cls_007"></Grid.Resources></span></div>
<div style="position:absolute;left:67.97px;top:124.50px" class="cls_007"><span class="cls_007"><Grid.ColumnDefinitions></span></div>
<div style="position:absolute;left:82.97px;top:138.00px" class="cls_007"><span class="cls_007"><ColumnDefinition Width="Auto" SharedSizeGroup="Label" /></span></div>
<div style="position:absolute;left:82.97px;top:151.50px" class="cls_007"><span class="cls_007"><ColumnDefinition /></span></div>
<div style="position:absolute;left:67.97px;top:165.00px" class="cls_007"><span class="cls_007"></Grid.ColumnDefinitions></span></div>
<div style="position:absolute;left:67.97px;top:178.50px" class="cls_007"><span class="cls_007"><Grid.RowDefinitions></span></div>
<div style="position:absolute;left:82.97px;top:192.00px" class="cls_007"><span class="cls_007"><RowDefinition Height="Auto" /></span></div>
<div style="position:absolute;left:82.97px;top:205.50px" class="cls_007"><span class="cls_007"><RowDefinition Height="Auto" /></span></div>
<div style="position:absolute;left:82.97px;top:219.00px" class="cls_007"><span class="cls_007"><RowDefinition Height="Auto" /></span></div>
<div style="position:absolute;left:67.97px;top:232.50px" class="cls_007"><span class="cls_007"></Grid.RowDefinitions></span></div>
<div style="position:absolute;left:67.97px;top:246.00px" class="cls_007"><span class="cls_007"><TextBlock Text="Name" /></span></div>
<div style="position:absolute;left:67.97px;top:259.50px" class="cls_007"><span class="cls_007"><TextBox Grid.Column="1" Text="{Binding User.Name}" /></span></div>
<div style="position:absolute;left:67.97px;top:273.00px" class="cls_007"><span class="cls_007"><TextBlock Grid.Row="1" Text="Age" /></span></div>
<div style="position:absolute;left:67.97px;top:286.50px" class="cls_007"><span class="cls_007"><TextBox Grid.Row="1" Grid.Column="1" Text="{Binding User.Age}"</span></div>
<div style="position:absolute;left:52.98px;top:300.00px" class="cls_007"><span class="cls_007">/></span></div>
<div style="position:absolute;left:67.97px;top:313.50px" class="cls_007"><span class="cls_007"><Controls:AddressControl Grid.Row="2" Grid.ColumnSpan="2"</span></div>
<div style="position:absolute;left:82.97px;top:327.00px" class="cls_007"><span class="cls_007">Address="{Binding User.Address}" /></span></div>
<div style="position:absolute;left:52.98px;top:340.50px" class="cls_007"><span class="cls_007"></Grid></span></div>
<div style="position:absolute;left:5.00px;top:360.75px" class="cls_004"><span class="cls_004">In this example, we can see the use of the </span><span class="cls_007">Grid.IsSharedSizeScope</span><span class="cls_004"> property on the</span></div>
<div style="position:absolute;left:5.00px;top:378.75px" class="cls_004"><span class="cls_004">outermost </span><span class="cls_007">Grid</span><span class="cls_004"> panel. Remember that the </span><span class="cls_007">SharedSizeGroup</span><span class="cls_004"> property was set in the</span></div>
<div style="position:absolute;left:5.00px;top:396.75px" class="cls_007"><span class="cls_007">AddressControl</span><span class="cls_004"> XAML, although without this setting on the outer </span><span class="cls_007">Grid</span><span class="cls_004">, that does nothing by</span></div>
<div style="position:absolute;left:5.00px;top:414.75px" class="cls_004"><span class="cls_004">itself.</span></div>
<div style="position:absolute;left:5.00px;top:432.75px" class="cls_004"><span class="cls_004">Looking at the outer panel's column definitions, we can see that we have also set the</span></div>
<div style="position:absolute;left:5.00px;top:450.75px" class="cls_007"><span class="cls_007">SharedSizeGroup</span><span class="cls_004"> property to the same value on the left column, so that the two panels'</span></div>
<div style="position:absolute;left:5.00px;top:468.75px" class="cls_004"><span class="cls_004">columns will be aligned.</span></div>
<div style="position:absolute;left:5.00px;top:486.75px" class="cls_004"><span class="cls_004">We can skip over the two styles that are declared in the panel's </span><span class="cls_007">Resources</span><span class="cls_004"> section, as in a</span></div>
<div style="position:absolute;left:5.00px;top:504.75px" class="cls_004"><span class="cls_004">proper application, these would most likely reside in the application resources file. In the</span></div>
<div style="position:absolute;left:5.00px;top:522.75px" class="cls_004"><span class="cls_004">remainder of the View, we simply have a couple of rows of user properties and then the</span></div>
<div style="position:absolute;left:5.00px;top:540.75px" class="cls_007"><span class="cls_007">AddressControl</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:558.75px" class="cls_004"><span class="cls_004">This code assumes that we have declared an </span><span class="cls_007">Address</span><span class="cls_004"> property of type </span><span class="cls_007">Address</span><span class="cls_004"> in our </span><span class="cls_007">User</span></div>
<div style="position:absolute;left:5.00px;top:576.75px" class="cls_004"><span class="cls_004">class and populated it with suitable values in the </span><span class="cls_007">UserViewModel</span><span class="cls_004"> class. Note how we data</span></div>
<div style="position:absolute;left:5.00px;top:594.75px" class="cls_004"><span class="cls_004">bind the </span><span class="cls_007">Address</span><span class="cls_004"> property of the </span><span class="cls_007">User</span><span class="cls_004"> class to the </span><span class="cls_007">Address</span><span class="cls_004"> property of the control, rather</span></div>
<div style="position:absolute;left:5.00px;top:612.75px" class="cls_004"><span class="cls_004">than setting the </span><span class="cls_007">DataContext</span><span class="cls_004"> property. As the control's internal controls are data bound</span></div>
<div style="position:absolute;left:5.00px;top:630.75px" class="cls_004"><span class="cls_004">using </span><span class="cls_007">RelativeSource</span><span class="cls_004"> bindings which specify their own binding source, they do not require</span></div>
<div style="position:absolute;left:5.00px;top:648.75px" class="cls_004"><span class="cls_004">any </span><span class="cls_007">DataContext</span><span class="cls_004"> to be set. In fact, doing so in this example would stop it from working.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:175638px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background221.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_008"><span class="cls_008">Creating custom controls</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">When using WPF, we can generally create the UI that we want using the many techniques</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">already discussed in this book. However, in the cases when we require a totally unique</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">control with both a custom drawn appearance and custom functionality, then we may need</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">to declare a custom control.</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">Developing custom controls is very different to creating </span><span class="cls_007">UserControl</span><span class="cls_004"> elements and it can</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">take some time to master this. To start with, we will need to add a new project of type</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_005"><span class="cls_005">WPF Custom Control Library</span><span class="cls_004"> to declare them in. Also, instead of having a XAML page</span></div>
<div style="position:absolute;left:5.00px;top:166.50px" class="cls_004"><span class="cls_004">and a code behind file, we only have the code file. At this point, you may be wondering</span></div>
<div style="position:absolute;left:5.00px;top:184.50px" class="cls_004"><span class="cls_004">where we define what our control should look like.</span></div>
<div style="position:absolute;left:5.00px;top:202.50px" class="cls_004"><span class="cls_004">In fact, when defining a custom control, we declare our XAML in a separate file named</span></div>
<div style="position:absolute;left:5.00px;top:220.50px" class="cls_007"><span class="cls_007">Generic.xaml</span><span class="cls_004">, which is added by Visual Studio when we add our controls project. To clarify,</span></div>
<div style="position:absolute;left:5.00px;top:238.50px" class="cls_004"><span class="cls_004">the XAML for all of the custom controls that we declare in this project will go into this file.</span></div>
<div style="position:absolute;left:5.00px;top:256.50px" class="cls_004"><span class="cls_004">This does not relate to controls that extend the </span><span class="cls_007">UserControl</span><span class="cls_004"> class and we should not</span></div>
<div style="position:absolute;left:5.00px;top:274.50px" class="cls_004"><span class="cls_004">declare those in this project.</span></div>
<div style="position:absolute;left:5.00px;top:292.50px" class="cls_004"><span class="cls_004">This </span><span class="cls_007">Generic.xaml</span><span class="cls_004"> file gets added into a folder named </span><span class="cls_007">Themes</span><span class="cls_004"> in the root directory of our</span></div>
<div style="position:absolute;left:5.00px;top:310.50px" class="cls_005"><span class="cls_005">WPF Custom Control Library</span><span class="cls_004"> project, as this is where the Framework will look for the</span></div>
<div style="position:absolute;left:5.00px;top:329.25px" class="cls_004"><span class="cls_004">default styles of our custom controls. As such, we must declare the UI design of our control</span></div>
<div style="position:absolute;left:5.00px;top:347.25px" class="cls_004"><span class="cls_004">in a </span><span class="cls_007">ControlTemplate</span><span class="cls_004"> and set it to the </span><span class="cls_007">Template</span><span class="cls_004"> property in a style that targets the type of</span></div>
<div style="position:absolute;left:5.00px;top:365.25px" class="cls_004"><span class="cls_004">our control in this file.</span></div>
<div style="position:absolute;left:5.00px;top:383.25px" class="cls_004"><span class="cls_004">The style must be applied to all instances of our control and so the style is defined with the</span></div>
<div style="position:absolute;left:5.00px;top:401.25px" class="cls_007"><span class="cls_007">TargetType</span><span class="cls_004"> set, but without the </span><span class="cls_007">x:Key</span><span class="cls_004"> directive. If you remember, this will ensure that it is</span></div>
<div style="position:absolute;left:5.00px;top:419.25px" class="cls_004"><span class="cls_004">implicitly applied to all instances of our control that haven't an alternative template explicitly</span></div>
<div style="position:absolute;left:5.00px;top:437.25px" class="cls_004"><span class="cls_004">applied.</span></div>
<div style="position:absolute;left:5.00px;top:455.25px" class="cls_004"><span class="cls_004">A further difference is that we cannot directly reference any of the controls that are defined</span></div>
<div style="position:absolute;left:5.00px;top:473.25px" class="cls_004"><span class="cls_004">within the style in the </span><span class="cls_007">Generic.xaml</span><span class="cls_004"> file. If you recall, when we provided a new template for</span></div>
<div style="position:absolute;left:5.00px;top:491.25px" class="cls_004"><span class="cls_004">the built-in controls, we were under no obligation to provide the same controls that were</span></div>
<div style="position:absolute;left:5.00px;top:509.25px" class="cls_004"><span class="cls_004">originally used. Therefore, if we tried to access a control from our original template that had</span></div>
<div style="position:absolute;left:5.00px;top:527.25px" class="cls_004"><span class="cls_004">been replaced, it would cause an error.</span></div>
<div style="position:absolute;left:5.00px;top:545.25px" class="cls_004"><span class="cls_004">Instead, we generally need to access them by overriding the </span><span class="cls_007">FrameworkElement.</span></div>
<div style="position:absolute;left:5.00px;top:563.25px" class="cls_007"><span class="cls_007">OnApplyTemplate</span><span class="cls_004"> method, which is raised once our default template has been applied to the</span></div>
<div style="position:absolute;left:5.00px;top:581.25px" class="cls_004"><span class="cls_004">instance of our control. In this method, we need to almost expect that our required</span></div>
<div style="position:absolute;left:5.00px;top:599.25px" class="cls_004"><span class="cls_004">control(s) will be missing and ensure that no errors occur if that is the case.</span></div>
<div style="position:absolute;left:5.00px;top:617.25px" class="cls_004"><span class="cls_004">Let's look at a simple example of a custom control that creates a meter that can be used to</span></div>
<div style="position:absolute;left:5.00px;top:635.25px" class="cls_004"><span class="cls_004">monitor CPU activity, RAM usage, audio loudness, or any other regularly changing value.</span></div>
<div style="position:absolute;left:5.00px;top:653.25px" class="cls_004"><span class="cls_004">We'll first need to create a new project of type </span><span class="cls_005">WPF Custom Control Library</span><span class="cls_004"> and rename</span></div>
<div style="position:absolute;left:5.00px;top:672.00px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">CustomControl1.cs</span><span class="cls_004"> class that Visual Studio adds for us to </span><span class="cls_007">Meter.cs</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:690.00px" class="cls_004"><span class="cls_004">Note that we can only add a custom control to a project of this type and that when the</span></div>
<div style="position:absolute;left:5.00px;top:708.00px" class="cls_004"><span class="cls_004">project is added, Visual Studio will also add our </span><span class="cls_007">Themes</span><span class="cls_004"> folder and </span><span class="cls_007">Generic.xaml</span><span class="cls_004"> file, with a</span></div>
<div style="position:absolute;left:5.00px;top:726.00px" class="cls_004"><span class="cls_004">style for our control already declared inside it. Let's see the code in the </span><span class="cls_007">Meter.cs</span><span class="cls_004"> file.</span></div>
<div style="position:absolute;left:52.98px;top:749.25px" class="cls_007"><span class="cls_007">using System;</span></div>
<div style="position:absolute;left:52.98px;top:762.75px" class="cls_007"><span class="cls_007">using System.Windows;</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:176440px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background222.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:3.00px" class="cls_007"><span class="cls_007">using System.Windows.Controls;</span></div>
<div style="position:absolute;left:52.98px;top:30.00px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.CustomControls</span></div>
<div style="position:absolute;left:52.98px;top:43.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:57.00px" class="cls_007"><span class="cls_007">public class Meter : Control</span></div>
<div style="position:absolute;left:67.97px;top:70.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:84.00px" class="cls_007"><span class="cls_007">static Meter()</span></div>
<div style="position:absolute;left:82.97px;top:97.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:111.00px" class="cls_007"><span class="cls_007">DefaultStyleKeyProperty.OverrideMetadata(typeof(Meter),</span></div>
<div style="position:absolute;left:112.96px;top:124.50px" class="cls_007"><span class="cls_007">new FrameworkPropertyMetadata(typeof(Meter)));</span></div>
<div style="position:absolute;left:82.97px;top:138.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:165.00px" class="cls_007"><span class="cls_007">public static readonly DependencyProperty ValueProperty =</span></div>
<div style="position:absolute;left:97.96px;top:178.50px" class="cls_007"><span class="cls_007">DependencyProperty.Register(nameof(Value),</span></div>
<div style="position:absolute;left:97.96px;top:192.00px" class="cls_007"><span class="cls_007">typeof(double), typeof(Meter),</span></div>
<div style="position:absolute;left:97.96px;top:205.50px" class="cls_007"><span class="cls_007">new PropertyMetadata(0.0, OnValueChanged, CoerceValue));</span></div>
<div style="position:absolute;left:82.97px;top:232.50px" class="cls_007"><span class="cls_007">private static object CoerceValue(DependencyObject</span></div>
<div style="position:absolute;left:52.98px;top:246.00px" class="cls_007"><span class="cls_007">dependencyObject,</span></div>
<div style="position:absolute;left:97.96px;top:259.50px" class="cls_007"><span class="cls_007">object value)</span></div>
<div style="position:absolute;left:82.97px;top:273.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:286.50px" class="cls_007"><span class="cls_007">return Math.Min(Math.Max((double)value, 0.0), 1.0);</span></div>
<div style="position:absolute;left:82.97px;top:300.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:327.00px" class="cls_007"><span class="cls_007">private static void OnValueChanged(DependencyObject</span></div>
<div style="position:absolute;left:52.98px;top:340.50px" class="cls_007"><span class="cls_007">dependencyObject,</span></div>
<div style="position:absolute;left:97.96px;top:354.00px" class="cls_007"><span class="cls_007">DependencyPropertyChangedEventArgs e)</span></div>
<div style="position:absolute;left:82.97px;top:367.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:381.00px" class="cls_007"><span class="cls_007">Meter meter = (Meter)dependencyObject;</span></div>
<div style="position:absolute;left:97.96px;top:394.50px" class="cls_007"><span class="cls_007">meter.SetClipRect(meter);</span></div>
<div style="position:absolute;left:82.97px;top:408.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:435.00px" class="cls_007"><span class="cls_007">public double Value</span></div>
<div style="position:absolute;left:82.97px;top:448.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:462.00px" class="cls_007"><span class="cls_007">get { return (double)GetValue(ValueProperty); }</span></div>
<div style="position:absolute;left:97.96px;top:475.50px" class="cls_007"><span class="cls_007">set { SetValue(ValueProperty, value); }</span></div>
<div style="position:absolute;left:82.97px;top:489.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:516.00px" class="cls_007"><span class="cls_007">public static readonly DependencyPropertyKey</span></div>
<div style="position:absolute;left:52.98px;top:529.50px" class="cls_007"><span class="cls_007">clipRectPropertyKey =</span></div>
<div style="position:absolute;left:97.96px;top:543.00px" class="cls_007"><span class="cls_007">DependencyProperty.RegisterReadOnly(nameof(ClipRect),</span></div>
<div style="position:absolute;left:52.98px;top:556.50px" class="cls_007"><span class="cls_007">typeof(Rect),</span></div>
<div style="position:absolute;left:97.96px;top:570.00px" class="cls_007"><span class="cls_007">typeof(Meter), new PropertyMetadata(new Rect()));</span></div>
<div style="position:absolute;left:82.97px;top:597.00px" class="cls_007"><span class="cls_007">public static readonly DependencyProperty ClipRectProperty =</span></div>
<div style="position:absolute;left:97.96px;top:610.50px" class="cls_007"><span class="cls_007">clipRectPropertyKey.DependencyProperty;</span></div>
<div style="position:absolute;left:82.97px;top:637.50px" class="cls_007"><span class="cls_007">public Rect ClipRect</span></div>
<div style="position:absolute;left:82.97px;top:651.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:664.50px" class="cls_007"><span class="cls_007">get { return (Rect)GetValue(ClipRectProperty); }</span></div>
<div style="position:absolute;left:97.96px;top:678.00px" class="cls_007"><span class="cls_007">private set { SetValue(clipRectPropertyKey, value); }</span></div>
<div style="position:absolute;left:82.97px;top:691.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:718.50px" class="cls_007"><span class="cls_007">public override void OnApplyTemplate()</span></div>
<div style="position:absolute;left:82.97px;top:732.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:745.50px" class="cls_007"><span class="cls_007">SetClipRect(this);</span></div>
<div style="position:absolute;left:82.97px;top:759.00px" class="cls_007"><span class="cls_007">}</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:177242px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background223.jpg" width=612 height=792></div>
<div style="position:absolute;left:82.97px;top:3.00px" class="cls_007"><span class="cls_007">private void SetClipRect(Meter meter)</span></div>
<div style="position:absolute;left:82.97px;top:16.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:30.00px" class="cls_007"><span class="cls_007">double barSize = meter.Value * meter.Height;</span></div>
<div style="position:absolute;left:97.96px;top:43.50px" class="cls_007"><span class="cls_007">meter.ClipRect =</span></div>
<div style="position:absolute;left:112.96px;top:57.00px" class="cls_007"><span class="cls_007">new Rect(0, meter.Height - barSize, meter.Width, barSize);</span></div>
<div style="position:absolute;left:82.97px;top:70.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:84.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:97.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:117.75px" class="cls_004"><span class="cls_004">This is a relatively small class, with only two Dependency Properties and their associated</span></div>
<div style="position:absolute;left:5.00px;top:135.75px" class="cls_004"><span class="cls_004">CLR property wrappers and callback handlers. Of particular note is the class's static</span></div>
<div style="position:absolute;left:5.00px;top:153.75px" class="cls_004"><span class="cls_004">constructor and the use of the </span><span class="cls_007">DefaultStyleKeyProperty.OverrideMetadata</span><span class="cls_004"> method.</span></div>
<div style="position:absolute;left:5.00px;top:171.75px" class="cls_004"><span class="cls_004">This is also added by Visual Studio when adding the class and is required to override the</span></div>
<div style="position:absolute;left:5.00px;top:189.75px" class="cls_004"><span class="cls_004">type specific metadata of the </span><span class="cls_007">DefaultStyleKey</span><span class="cls_004"> Dependency Property when we derive a</span></div>
<div style="position:absolute;left:5.00px;top:207.75px" class="cls_004"><span class="cls_004">custom class from the </span><span class="cls_007">FrameworkElement</span><span class="cls_004"> class.</span></div>
<div style="position:absolute;left:5.00px;top:225.75px" class="cls_004"><span class="cls_004">Specifically, this key is used by the Framework to find the default theme style for our control</span></div>
<div style="position:absolute;left:5.00px;top:243.75px" class="cls_004"><span class="cls_004">and so, by passing the type of our class into the </span><span class="cls_007">OverrideMetadata</span><span class="cls_004"> method, we are telling</span></div>
<div style="position:absolute;left:5.00px;top:261.75px" class="cls_004"><span class="cls_004">the Framework to look for a default style for this type in our </span><span class="cls_007">Themes</span><span class="cls_004"> folder.</span></div>
<div style="position:absolute;left:5.00px;top:279.75px" class="cls_004"><span class="cls_004">If you remember, the theme styles are the last place that the Framework will look for the</span></div>
<div style="position:absolute;left:5.00px;top:297.75px" class="cls_004"><span class="cls_004">style of a specific type and declaring styles just about anywhere else in the application will</span></div>
<div style="position:absolute;left:5.00px;top:315.75px" class="cls_004"><span class="cls_004">override the default styles defined here.</span></div>
<div style="position:absolute;left:5.00px;top:333.75px" class="cls_004"><span class="cls_004">The first Dependency Property is the main </span><span class="cls_007">Value</span><span class="cls_004"> property of the control and this is used to</span></div>
<div style="position:absolute;left:5.00px;top:351.75px" class="cls_004"><span class="cls_004">determine the size of the visible meter bar. This property defines a default value of </span><span class="cls_007">0.0</span><span class="cls_004"> and</span></div>
<div style="position:absolute;left:5.00px;top:369.75px" class="cls_004"><span class="cls_004">attaches the </span><span class="cls_007">CoerceValue</span><span class="cls_004"> and </span><span class="cls_007">OnValueChanged</span><span class="cls_004"> callback handlers.</span></div>
<div style="position:absolute;left:5.00px;top:387.75px" class="cls_004"><span class="cls_004">In the </span><span class="cls_007">CoerceValue</span><span class="cls_004"> handling method, we ensure that the output value always remains</span></div>
<div style="position:absolute;left:5.00px;top:405.75px" class="cls_004"><span class="cls_004">between </span><span class="cls_007">0.0</span><span class="cls_004"> and </span><span class="cls_007">1.0</span><span class="cls_004">, as that is the scale that we will be using. In the </span><span class="cls_007">OnValueChanged</span></div>
<div style="position:absolute;left:5.00px;top:423.75px" class="cls_004"><span class="cls_004">handler, we update the value of the other Dependency Property, </span><span class="cls_007">ClipRect</span><span class="cls_004">, dependent upon</span></div>
<div style="position:absolute;left:5.00px;top:441.75px" class="cls_004"><span class="cls_004">the input value.</span></div>
<div style="position:absolute;left:5.00px;top:459.75px" class="cls_004"><span class="cls_004">To do this, we first cast the </span><span class="cls_007">dependencyObject</span><span class="cls_004"> input parameter to our </span><span class="cls_007">Meter</span><span class="cls_004"> type and then</span></div>
<div style="position:absolute;left:5.00px;top:477.75px" class="cls_004"><span class="cls_004">pass that instance to the </span><span class="cls_007">SetClipRect</span><span class="cls_004"> method. In this method, we calculate the relative size</span></div>
<div style="position:absolute;left:5.00px;top:495.75px" class="cls_004"><span class="cls_004">of the meter bar and define the </span><span class="cls_007">Rect</span><span class="cls_004"> element for the </span><span class="cls_007">ClipRect</span><span class="cls_004"> Dependency Property</span></div>
<div style="position:absolute;left:5.00px;top:513.75px" class="cls_004"><span class="cls_004">accordingly.</span></div>
<div style="position:absolute;left:5.00px;top:531.75px" class="cls_004"><span class="cls_004">Next, we see the CLR property wrapper for the </span><span class="cls_007">Value</span><span class="cls_004"> Dependency Property and then the</span></div>
<div style="position:absolute;left:5.00px;top:549.75px" class="cls_004"><span class="cls_004">declaration of the </span><span class="cls_007">ClipRect</span><span class="cls_004"> Dependency Property. Note that we declare it using a</span></div>
<div style="position:absolute;left:5.00px;top:567.75px" class="cls_007"><span class="cls_007">DependencyPropertyKey</span><span class="cls_004"> element, thus making it a read-only property, because it is only for</span></div>
<div style="position:absolute;left:5.00px;top:585.75px" class="cls_004"><span class="cls_004">internal use and has no value being exposed publicly. The actual </span><span class="cls_007">ClipRect</span><span class="cls_004"> Dependency</span></div>
<div style="position:absolute;left:5.00px;top:603.75px" class="cls_004"><span class="cls_004">Property comes from this key element.</span></div>
<div style="position:absolute;left:5.00px;top:621.75px" class="cls_004"><span class="cls_004">After this, we see the CLR property wrapper for the </span><span class="cls_007">ClipRect</span><span class="cls_004"> Dependency Property and</span></div>
<div style="position:absolute;left:5.00px;top:639.75px" class="cls_004"><span class="cls_004">then we come to the aforementioned </span><span class="cls_007">OnApplyTemplate</span><span class="cls_004"> method. In our case, the purpose of</span></div>
<div style="position:absolute;left:5.00px;top:657.75px" class="cls_004"><span class="cls_004">overriding this method is because often, data bound values will be set before the control's</span></div>
<div style="position:absolute;left:5.00px;top:675.75px" class="cls_004"><span class="cls_004">template has been applied and so we would not be able to correctly set the size of the</span></div>
<div style="position:absolute;left:5.00px;top:693.75px" class="cls_004"><span class="cls_004">meter bar from those values.</span></div>
<div style="position:absolute;left:5.00px;top:711.75px" class="cls_004"><span class="cls_004">Therefore, when the template has been applied and the control has been arranged and</span></div>
<div style="position:absolute;left:5.00px;top:729.75px" class="cls_004"><span class="cls_004">sized, we call the </span><span class="cls_007">SetClipRect</span><span class="cls_004"> method in order to set the </span><span class="cls_007">Rect</span><span class="cls_004"> element for the </span><span class="cls_007">ClipRect</span></div>
<div style="position:absolute;left:5.00px;top:747.75px" class="cls_004"><span class="cls_004">Dependency Property to the appropriate value. Before this point in time, the </span><span class="cls_007">Heig</span><span class="cls_004"> </span><span class="cls_007">ht</span><span class="cls_004"> and</span></div>
<div style="position:absolute;left:5.00px;top:765.75px" class="cls_007"><span class="cls_007">Weight</span><span class="cls_004"> properties of the </span><span class="cls_007">meter</span><span class="cls_004"> instance will be </span><span class="cls_007">double.NaN</span><span class="cls_004"> (Not a Number) and cannot be</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:178044px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background224.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">used to size the </span><span class="cls_007">Rect</span><span class="cls_004"> element correctly.</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">When this method is called, we can rest assured that the </span><span class="cls_007">Heig</span><span class="cls_004"> </span><span class="cls_007">ht</span><span class="cls_004"> and </span><span class="cls_007">Weight</span><span class="cls_004"> properties of</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">meter</span><span class="cls_004"> instance will have valid values. Note that had we needed to access any elements</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">from our template, we could have called the </span><span class="cls_007">FrameworkTemplate.FindName</span><span class="cls_004"> method from this</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">method, on the </span><span class="cls_007">ControlTemplate</span><span class="cls_004"> object that is specified by our control's </span><span class="cls_007">Template</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">Imagine that we had named a </span><span class="cls_007">Rectangle</span><span class="cls_004"> element in our XAML to </span><span class="cls_007">PART_Rectangle</span><span class="cls_004">, we could</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">access it from the </span><span class="cls_007">OnApplyTemplate</span><span class="cls_004"> method like this.</span></div>
<div style="position:absolute;left:52.98px;top:135.00px" class="cls_007"><span class="cls_007">Rectangle rectangle =</span></div>
<div style="position:absolute;left:52.98px;top:148.50px" class="cls_007"><span class="cls_007">(Rectangle)Template.FindName("PART_Rectangle", this);</span></div>
<div style="position:absolute;left:52.98px;top:162.00px" class="cls_007"><span class="cls_007">if (rectangle != null)</span></div>
<div style="position:absolute;left:52.98px;top:175.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:189.00px" class="cls_007"><span class="cls_007">// Do something with rectangle</span></div>
<div style="position:absolute;left:52.98px;top:202.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:222.75px" class="cls_004"><span class="cls_004">Note that we always need to check for null, because the applied template may be a custom</span></div>
<div style="position:absolute;left:5.00px;top:240.75px" class="cls_004"><span class="cls_004">template that does not contain the </span><span class="cls_007">Rectangle</span><span class="cls_004"> element at all. Note also that when we require</span></div>
<div style="position:absolute;left:5.00px;top:258.75px" class="cls_004"><span class="cls_004">the existence of a particular element in the template, we can decorate our custom control</span></div>
<div style="position:absolute;left:5.00px;top:276.75px" class="cls_004"><span class="cls_004">class declaration with a </span><span class="cls_007">TemplatePartAttribute</span><span class="cls_004">, that specifies the details of the required</span></div>
<div style="position:absolute;left:5.00px;top:294.75px" class="cls_004"><span class="cls_004">control.</span></div>
<div style="position:absolute;left:52.98px;top:318.00px" class="cls_007"><span class="cls_007">[TemplatePart(Name = "PART_Rectangle", Type = typeof(Rectangle))]</span></div>
<div style="position:absolute;left:52.98px;top:331.50px" class="cls_007"><span class="cls_007">public class Meter : Control</span></div>
<div style="position:absolute;left:52.98px;top:345.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:52.98px;top:372.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:392.25px" class="cls_004"><span class="cls_004">This will not enforce anything and will not raise any compilation errors if the named part is</span></div>
<div style="position:absolute;left:5.00px;top:410.25px" class="cls_004"><span class="cls_004">not included in a custom template, but it will be used in documentation and by various XAML</span></div>
<div style="position:absolute;left:5.00px;top:428.25px" class="cls_004"><span class="cls_004">tools. It helps users of our custom controls to find out which elements are required when</span></div>
<div style="position:absolute;left:5.00px;top:446.25px" class="cls_004"><span class="cls_004">they provide custom templates.</span></div>
<div style="position:absolute;left:5.00px;top:464.25px" class="cls_004"><span class="cls_004">Now that we've seen the inner workings of this control, let's take a look at the XAML of the</span></div>
<div style="position:absolute;left:5.00px;top:482.25px" class="cls_004"><span class="cls_004">default style of our control in the </span><span class="cls_007">Generic.xaml</span><span class="cls_004"> file to see how the </span><span class="cls_007">ClipRect</span><span class="cls_004"> property is</span></div>
<div style="position:absolute;left:5.00px;top:500.25px" class="cls_004"><span class="cls_004">used.</span></div>
<div style="position:absolute;left:52.98px;top:523.50px" class="cls_007"><span class="cls_007"><ResourceDictionary</span></div>
<div style="position:absolute;left:67.97px;top:537.00px" class="cls_007"><span class="cls_007">xmlns="</span><A HREF="http://schemas.microsoft.com/winfx/2006/xaml/presentation"/">http://schemas.microsoft.com/winfx/2006/xaml/presentation"</A> </div>
<div style="position:absolute;left:67.97px;top:550.50px" class="cls_007"><span class="cls_007">xmlns:x="</span><A HREF="http://schemas.microsoft.com/winfx/2006/xaml"/">http://schemas.microsoft.com/winfx/2006/xaml"</A> </div>
<div style="position:absolute;left:67.97px;top:564.00px" class="cls_007"><span class="cls_007">xmlns:CustomControls=</span></div>
<div style="position:absolute;left:82.97px;top:577.50px" class="cls_007"><span class="cls_007">"clr-namespace:CompanyName.ApplicationName.CustomControls"></span></div>
<div style="position:absolute;left:67.97px;top:591.00px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type CustomControls:Meter}"></span></div>
<div style="position:absolute;left:82.97px;top:604.50px" class="cls_007"><span class="cls_007"><Setter Property="Template"></span></div>
<div style="position:absolute;left:97.96px;top:618.00px" class="cls_007"><span class="cls_007"><Setter.Value></span></div>
<div style="position:absolute;left:112.96px;top:631.50px" class="cls_007"><span class="cls_007"><ControlTemplate TargetType="{x:Type</span></div>
<div style="position:absolute;left:127.95px;top:645.00px" class="cls_007"><span class="cls_007">CustomControls:Meter}"></span></div>
<div style="position:absolute;left:127.95px;top:658.50px" class="cls_007"><span class="cls_007"><ControlTemplate.Resources></span></div>
<div style="position:absolute;left:142.94px;top:672.00px" class="cls_007"><span class="cls_007"><LinearGradientBrush x:Key="ScaleColours"</span></div>
<div style="position:absolute;left:157.94px;top:685.50px" class="cls_007"><span class="cls_007">StartPoint="0,1" EndPoint="0,0"></span></div>
<div style="position:absolute;left:157.94px;top:699.00px" class="cls_007"><span class="cls_007"><GradientStop Color="LightGreen" /></span></div>
<div style="position:absolute;left:157.94px;top:712.50px" class="cls_007"><span class="cls_007"><GradientStop Color="Yellow" Offset="0.5" /></span></div>
<div style="position:absolute;left:157.94px;top:726.00px" class="cls_007"><span class="cls_007"><GradientStop Color="Orange" Offset="0.75" /></span></div>
<div style="position:absolute;left:157.94px;top:739.50px" class="cls_007"><span class="cls_007"><GradientStop Color="Red" Offset="1.0" /></span></div>
<div style="position:absolute;left:142.94px;top:753.00px" class="cls_007"><span class="cls_007"></LinearGradientBrush></span></div>
<div style="position:absolute;left:127.95px;top:766.50px" class="cls_007"><span class="cls_007"></ControlTemplate.Resources></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:178846px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background225.jpg" width=612 height=792></div>
<div style="position:absolute;left:127.95px;top:3.00px" class="cls_007"><span class="cls_007"><Border Background="{TemplateBinding Background}"</span></div>
<div style="position:absolute;left:142.94px;top:16.50px" class="cls_007"><span class="cls_007">BorderBrush="{TemplateBinding BorderBrush}"</span></div>
<div style="position:absolute;left:142.94px;top:30.00px" class="cls_007"><span class="cls_007">BorderThickness="{TemplateBinding BorderThickness}"></span></div>
<div style="position:absolute;left:142.94px;top:43.50px" class="cls_007"><span class="cls_007"><Border.ToolTip></span></div>
<div style="position:absolute;left:157.94px;top:57.00px" class="cls_007"><span class="cls_007"><TextBlock Text="{Binding Value, StringFormat={}</span></div>
<div style="position:absolute;left:52.98px;top:70.50px" class="cls_007"><span class="cls_007">{0:P0}}" /></span></div>
<div style="position:absolute;left:142.94px;top:84.00px" class="cls_007"><span class="cls_007"></Border.ToolTip></span></div>
<div style="position:absolute;left:142.94px;top:97.50px" class="cls_007"><span class="cls_007"><Rectangle Fill="{StaticResource ScaleColours}"</span></div>
<div style="position:absolute;left:157.94px;top:111.00px" class="cls_007"><span class="cls_007">HorizontalAlignment="Stretch"</span></div>
<div style="position:absolute;left:52.98px;top:124.50px" class="cls_007"><span class="cls_007">VerticalAlignment="Stretch"</span></div>
<div style="position:absolute;left:157.94px;top:138.00px" class="cls_007"><span class="cls_007">SnapsToDevicePixels="True" Name="PART_Rectangle"></span></div>
<div style="position:absolute;left:157.94px;top:151.50px" class="cls_007"><span class="cls_007"><Rectangle.Clip></span></div>
<div style="position:absolute;left:172.93px;top:165.00px" class="cls_007"><span class="cls_007"><RectangleGeometry Rect="{Binding ClipRect,</span></div>
<div style="position:absolute;left:187.92px;top:178.50px" class="cls_007"><span class="cls_007">RelativeSource={RelativeSource</span></div>
<div style="position:absolute;left:187.92px;top:192.00px" class="cls_007"><span class="cls_007">AncestorType={x:Type CustomControls:Meter}}}" /></span></div>
<div style="position:absolute;left:157.94px;top:205.50px" class="cls_007"><span class="cls_007"></Rectangle.Clip></span></div>
<div style="position:absolute;left:142.94px;top:219.00px" class="cls_007"><span class="cls_007"></Rectangle></span></div>
<div style="position:absolute;left:127.95px;top:232.50px" class="cls_007"><span class="cls_007"></Border></span></div>
<div style="position:absolute;left:112.96px;top:246.00px" class="cls_007"><span class="cls_007"></ControlTemplate></span></div>
<div style="position:absolute;left:97.96px;top:259.50px" class="cls_007"><span class="cls_007"></Setter.Value></span></div>
<div style="position:absolute;left:82.97px;top:273.00px" class="cls_007"><span class="cls_007"></Setter></span></div>
<div style="position:absolute;left:67.97px;top:286.50px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:52.98px;top:300.00px" class="cls_007"><span class="cls_007"></ResourceDictionary></span></div>
<div style="position:absolute;left:5.00px;top:333.00px" class="cls_004"><span class="cls_004">When each custom control class is created in a </span><span class="cls_005">WPF Custom Control Library</span><span class="cls_004"> project,</span></div>
<div style="position:absolute;left:5.00px;top:351.75px" class="cls_004"><span class="cls_004">Visual Studio adds an almost empty default style that sets a basic </span><span class="cls_007">ControlTemplate</span><span class="cls_004"> and</span></div>
<div style="position:absolute;left:5.00px;top:369.75px" class="cls_004"><span class="cls_004">targets the type of the class into the </span><span class="cls_007">Generic.xaml</span><span class="cls_004"> file. We just need to define our custom</span></div>
<div style="position:absolute;left:5.00px;top:387.75px" class="cls_004"><span class="cls_004">XAML within this template.</span></div>
<div style="position:absolute;left:5.00px;top:405.75px" class="cls_004"><span class="cls_004">We start by declaring the </span><span class="cls_007">ScaleColours</span><span class="cls_004"> gradient brush resource within the template. Note</span></div>
<div style="position:absolute;left:5.00px;top:423.75px" class="cls_004"><span class="cls_004">that the default value for the </span><span class="cls_007">Offset</span><span class="cls_004"> property of a </span><span class="cls_007">GradientStop</span><span class="cls_004"> element is </span><span class="cls_007">0</span><span class="cls_004"> and so, we</span></div>
<div style="position:absolute;left:5.00px;top:441.75px" class="cls_004"><span class="cls_004">can omit the setting of this property, if that is the value that we want it set to. Therefore,</span></div>
<div style="position:absolute;left:5.00px;top:459.75px" class="cls_004"><span class="cls_004">when we see a declared</span><span class="cls_007"> GradientStop</span><span class="cls_004">, like the one with the </span><span class="cls_007">Color</span><span class="cls_004"> property set to</span></div>
<div style="position:absolute;left:5.00px;top:477.75px" class="cls_007"><span class="cls_007">LightGreen</span><span class="cls_004">, we know its </span><span class="cls_007">Offset</span><span class="cls_004"> property is set to </span><span class="cls_007">0</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:495.75px" class="cls_004"><span class="cls_004">Our meter control is basically made up from a </span><span class="cls_007">Border</span><span class="cls_004"> element that surrounds a </span><span class="cls_007">Rectangle</span></div>
<div style="position:absolute;left:5.00px;top:513.75px" class="cls_004"><span class="cls_004">element. We use a </span><span class="cls_007">TemplateBinding</span><span class="cls_004"> to data bind the </span><span class="cls_007">Background</span><span class="cls_004">, </span><span class="cls_007">BorderBrush</span><span class="cls_004"> and</span></div>
<div style="position:absolute;left:5.00px;top:531.75px" class="cls_007"><span class="cls_007">BorderThickness</span><span class="cls_004"> properties of the </span><span class="cls_007">Border</span><span class="cls_004"> element.</span></div>
<div style="position:absolute;left:5.00px;top:549.75px" class="cls_004"><span class="cls_004">This enables users of the control to specify the border and background colors of the internal</span></div>
<div style="position:absolute;left:5.00px;top:567.75px" class="cls_007"><span class="cls_007">Border</span><span class="cls_004"> element of the meter control from outside the control. We could just as easily have</span></div>
<div style="position:absolute;left:5.00px;top:585.75px" class="cls_004"><span class="cls_004">exposed an additional brush property to replace the </span><span class="cls_007">ScaleColours</span><span class="cls_004"> resource and enable</span></div>
<div style="position:absolute;left:5.00px;top:603.75px" class="cls_004"><span class="cls_004">users to define their own meter scale brush.</span></div>
<div style="position:absolute;left:5.00px;top:621.75px" class="cls_004"><span class="cls_004">Note that we couldn't use a </span><span class="cls_007">TemplateBinding</span><span class="cls_004"> to data bind the </span><span class="cls_007">Value</span><span class="cls_004"> property in the </span><span class="cls_007">ToolTip</span></div>
<div style="position:absolute;left:5.00px;top:639.75px" class="cls_004"><span class="cls_004">element. This is not because we don't have access to it through the template, but because</span></div>
<div style="position:absolute;left:5.00px;top:657.75px" class="cls_004"><span class="cls_004">we need to use the </span><span class="cls_007">Binding.StringFormat</span><span class="cls_004"> property and the </span><span class="cls_007">P</span><span class="cls_004"> format specifier to transform</span></div>
<div style="position:absolute;left:5.00px;top:675.75px" class="cls_004"><span class="cls_004">our double property value to a percentage value.</span></div>
<div style="position:absolute;left:5.00px;top:693.75px" class="cls_004"><span class="cls_004">If you remember, a </span><span class="cls_007">TemplateBinding</span><span class="cls_004"> is a lightweight binding and does not offer this</span></div>
<div style="position:absolute;left:5.00px;top:711.75px" class="cls_004"><span class="cls_004">functionality. While it is beneficial to use it when we can, this example highlights the fact that</span></div>
<div style="position:absolute;left:5.00px;top:729.75px" class="cls_004"><span class="cls_004">we cannot use it in every circumstance.</span></div>
<div style="position:absolute;left:5.00px;top:747.75px" class="cls_004"><span class="cls_004">Finally, we come to the all-important </span><span class="cls_007">Rectangle</span><span class="cls_004"> element that is responsible for displaying</span></div>
<div style="position:absolute;left:5.00px;top:765.75px" class="cls_004"><span class="cls_004">the actual meter bar of our control. The </span><span class="cls_007">ScaleColours</span><span class="cls_004"> brush resource is used here to paint</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:179648px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background226.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">the background of the rectangle. We set the </span><span class="cls_007">SnapsToDevicePixels</span><span class="cls_004"> property to </span><span class="cls_007">true</span><span class="cls_004"> on this</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">element to ensure that the level that it displays is accurate and well-defined.</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">The magic in this control is formed by the use of the </span><span class="cls_007">UIElement.Clip</span><span class="cls_004"> property. Essentially,</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">this enables us to provide any type of </span><span class="cls_007">Geometry</span><span class="cls_004"> element to alter the shape and size of the</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">visible portion of a UI element. The geometry shape that we assign here will specify the</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">visible portion of the control.</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">In our case, we declare a </span><span class="cls_007">RectangleGeometry</span><span class="cls_004"> class, whose size and location are specified</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">by its </span><span class="cls_007">Rect</span><span class="cls_004"> property. We therefore data bind our </span><span class="cls_007">ClipRect</span><span class="cls_004"> Dependency Property to this</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_007"><span class="cls_007">Rect</span><span class="cls_004"> property, so that the sizes calculated from the incoming data values are represented</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">by this </span><span class="cls_007">RectangleGeometry</span><span class="cls_004"> instance and therefore, the visible part of the </span><span class="cls_007">Rectangle</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">element.</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">Note that we do this so that the gradient that is painted on the meter bar remains constant</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">and does not change with the height of the bar as its value changes. If we had simply</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">painted the background of the rectangle with the brush resource and adjusted its height, the</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">background gradient would move with the size of the meter bar and spoil the effect.</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">Therefore, the whole rectangle is always painted with the gradient brush and we simply use</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">its </span><span class="cls_007">Clip</span><span class="cls_004"> property to just display the appropriate part of it. In order to use it in one of our</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">Views, we'd first need to specify the </span><span class="cls_007">CustomControls</span><span class="cls_004"> XAML namespace prefix.</span></div>
<div style="position:absolute;left:52.98px;top:333.00px" class="cls_007"><span class="cls_007">xmlns:CustomControls="clr-namespace:CompanyName.ApplicationName.</span></div>
<div style="position:absolute;left:52.98px;top:360.00px" class="cls_007"><span class="cls_007">CustomControls;assembly=CompanyName.ApplicationName.CustomControls"</span></div>
<div style="position:absolute;left:5.00px;top:380.25px" class="cls_004"><span class="cls_004">We could then declare a number of them, data bind some appropriate properties to their</span></div>
<div style="position:absolute;left:5.00px;top:398.25px" class="cls_007"><span class="cls_007">Value</span><span class="cls_004"> property and set styles for them, just like any other control.</span></div>
<div style="position:absolute;left:52.98px;top:421.50px" class="cls_007"><span class="cls_007"><StackPanel Orientation="Horizontal" HorizontalAlignment="Center"></span></div>
<div style="position:absolute;left:67.97px;top:435.00px" class="cls_007"><span class="cls_007"><StackPanel.Resources></span></div>
<div style="position:absolute;left:82.97px;top:448.50px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type CustomControls:Meter}"></span></div>
<div style="position:absolute;left:97.96px;top:462.00px" class="cls_007"><span class="cls_007"><Setter Property="Background" Value="Black" /></span></div>
<div style="position:absolute;left:97.96px;top:475.50px" class="cls_007"><span class="cls_007"><Setter Property="BorderBrush" Value="Black" /></span></div>
<div style="position:absolute;left:97.96px;top:489.00px" class="cls_007"><span class="cls_007"><Setter Property="BorderThickness" Value="2" /></span></div>
<div style="position:absolute;left:97.96px;top:502.50px" class="cls_007"><span class="cls_007"><Setter Property="HorizontalAlignment" Value="Center" /></span></div>
<div style="position:absolute;left:97.96px;top:516.00px" class="cls_007"><span class="cls_007"><Setter Property="Width" Value="20" /></span></div>
<div style="position:absolute;left:97.96px;top:529.50px" class="cls_007"><span class="cls_007"><Setter Property="Height" Value="100" /></span></div>
<div style="position:absolute;left:82.97px;top:543.00px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:67.97px;top:556.50px" class="cls_007"><span class="cls_007"></StackPanel.Resources></span></div>
<div style="position:absolute;left:67.97px;top:570.00px" class="cls_007"><span class="cls_007"><CustomControls:Meter Value="{Binding CpuActivity}" /></span></div>
<div style="position:absolute;left:67.97px;top:583.50px" class="cls_007"><span class="cls_007"><CustomControls:Meter Value="{Binding DiskActivity}"</span></div>
<div style="position:absolute;left:52.98px;top:597.00px" class="cls_007"><span class="cls_007">Margin="10,0" /></span></div>
<div style="position:absolute;left:67.97px;top:610.50px" class="cls_007"><span class="cls_007"><CustomControls:Meter Value="{Binding NetworkActivity}" /></span></div>
<div style="position:absolute;left:52.98px;top:624.00px" class="cls_007"><span class="cls_007"></StackPanel></span></div>
<div style="position:absolute;left:5.00px;top:644.25px" class="cls_004"><span class="cls_004">Given some valid properties to data bind to, the preceding example would produce an</span></div>
<div style="position:absolute;left:5.00px;top:662.25px" class="cls_004"><span class="cls_004">output similar to the following:</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:180450px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background227.jpg" width=612 height=792></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:181252px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background228.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_008"><span class="cls_008">Summary</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">In this chapter, we've investigated the rich inheritance hierarchy of the built-in WPF controls,</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">determining which abilities comes from which base classes and seen how each control is</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">laid out by their containing panels. We've examined the differences between the different</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">panels and understand that some work better in certain conditions than others.</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">We've also uncovered the mysteries of the </span><span class="cls_007">ContentControl</span><span class="cls_004"> and </span><span class="cls_007">ItemsControl</span><span class="cls_004"> elements</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">and now have a good understanding of </span><span class="cls_007">ContentPresenter</span><span class="cls_004"> and </span><span class="cls_007">ItemsPresenter</span><span class="cls_004"> objects. We</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">moved on to discover a wide variety of ways for us to customize the built-in controls. Finally,</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">we considered how best to make our own controls.</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">In the next chapter, we will take a thorough look at the WPF animation system and discover</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">how we can utilize it in every day applications. We'll also find out a number of techniques to</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">fine-tune animations to get that perfect effect and discover how we can build animation</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">functionality into our application framework.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:182054px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background229.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_002"><span class="cls_002">Chapter 6. Mastering Practical Animations</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">WPF offers a wide range of animation possibilities, from the simple to the really quite</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">complex. We will thoroughly explore the WPF property animation system, yet focus</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">primarily on those parts that can be suitably applied to real-world business applications.</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">We'll investigate how to control running applications in real time and predominantly</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">concentrate on XAML-based syntax. We'll then see how we can build animations right into</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">our application framework.</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">In WPF, animations are created by repeatedly altering individual property values at regular</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">intervals. Animations are comprised of a number of components; we need a timing system,</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">an animation object that is responsible for updating the values of a particular type of object</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">and a suitable property to animate.</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">In order to be able to animate a property, it must be a Dependency Property of a</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_007"><span class="cls_007">DependencyObject</span><span class="cls_004"> and its type must implement the </span><span class="cls_007">IAnimatable</span><span class="cls_004"> interface. As most UI</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">controls extend the </span><span class="cls_007">DependencyObject</span><span class="cls_004"> class, this enables us to animate the properties of</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">most controls.</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">Furthermore, an animation object for the relevant type of the property must exist. In WPF,</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">the animation objects also double up as the timing system, as they extend the </span><span class="cls_007">Timeline</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_004"><span class="cls_004">class. Before investigating the various animation objects, let's first examine the timing</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_004"><span class="cls_004">system.</span></div>
<div style="position:absolute;left:5.00px;top:363.01px" class="cls_008"><span class="cls_008">Investigating timelines</span></div>
<div style="position:absolute;left:5.00px;top:399.75px" class="cls_004"><span class="cls_004">Animations require some kind of timing mechanism that is responsible for updating the</span></div>
<div style="position:absolute;left:5.00px;top:417.75px" class="cls_004"><span class="cls_004">relevant property values at the right time. In WPF, this timing mechanism is catered for by</span></div>
<div style="position:absolute;left:5.00px;top:435.75px" class="cls_004"><span class="cls_004">the abstract </span><span class="cls_007">Timeline</span><span class="cls_004"> class, which in short, represents a period of time. All of the available</span></div>
<div style="position:absolute;left:5.00px;top:453.75px" class="cls_004"><span class="cls_004">animation classes extend this class and add their own animation functionality.</span></div>
<div style="position:absolute;left:5.00px;top:471.75px" class="cls_004"><span class="cls_004">When a </span><span class="cls_007">Timeline</span><span class="cls_004"> class is used for animations, an internal copy is made and frozen, so that</span></div>
<div style="position:absolute;left:5.00px;top:489.75px" class="cls_004"><span class="cls_004">it is immutable. Additionally, a </span><span class="cls_007">Clock</span><span class="cls_004"> object is created to preserve the runtime timing state</span></div>
<div style="position:absolute;left:5.00px;top:507.75px" class="cls_004"><span class="cls_004">of the </span><span class="cls_007">Timeline</span><span class="cls_004"> object and is responsible for the actual timing of the animated property</span></div>
<div style="position:absolute;left:5.00px;top:525.75px" class="cls_004"><span class="cls_004">updates. The </span><span class="cls_007">Timeline</span><span class="cls_004"> object itself does little other than define the relevant period of time.</span></div>
<div style="position:absolute;left:5.00px;top:543.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">Clock</span><span class="cls_004"> object will be automatically created for us when we define a </span><span class="cls_007">Storyboard</span><span class="cls_004"> object,</span></div>
<div style="position:absolute;left:5.00px;top:561.75px" class="cls_004"><span class="cls_004">or call one of the </span><span class="cls_007">Animatable.BeginAnimation</span><span class="cls_004"> methods. Note that we do not typically need</span></div>
<div style="position:absolute;left:5.00px;top:579.75px" class="cls_004"><span class="cls_004">to concern ourselves with these </span><span class="cls_007">Clock</span><span class="cls_004"> objects directly, but it can be helpful to know about</span></div>
<div style="position:absolute;left:5.00px;top:597.75px" class="cls_004"><span class="cls_004">them in order to understand the bigger picture.</span></div>
<div style="position:absolute;left:5.00px;top:615.75px" class="cls_004"><span class="cls_004">There are a number of different types of </span><span class="cls_007">Timeline</span><span class="cls_004"> objects, from the </span><span class="cls_007">AnimationTimeline</span></div>
<div style="position:absolute;left:5.00px;top:633.75px" class="cls_004"><span class="cls_004">class to the </span><span class="cls_007">TimelineGroup</span><span class="cls_004"> and </span><span class="cls_007">ParallelTimeline</span><span class="cls_004"> classes. However, for animation</span></div>
<div style="position:absolute;left:5.00px;top:651.75px" class="cls_004"><span class="cls_004">purposes, we predominantly utilize the </span><span class="cls_007">Storyboard</span><span class="cls_004"> class, which extends the</span></div>
<div style="position:absolute;left:5.00px;top:669.75px" class="cls_007"><span class="cls_007">ParallelTimeline</span><span class="cls_004"> and the </span><span class="cls_007">TimelineGroup</span><span class="cls_004"> classes and adds animation-targeting properties</span></div>
<div style="position:absolute;left:5.00px;top:687.75px" class="cls_004"><span class="cls_004">and methods for controlling the timeline. Let's first investigate the main properties of the</span></div>
<div style="position:absolute;left:5.00px;top:705.75px" class="cls_004"><span class="cls_004">base </span><span class="cls_007">Timeline</span><span class="cls_004"> class.</span></div>
<div style="position:absolute;left:5.00px;top:723.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">Duration</span><span class="cls_004"> property specifies the time that is represented by the associated </span><span class="cls_007">Timeline</span></div>
<div style="position:absolute;left:5.00px;top:741.75px" class="cls_004"><span class="cls_004">object. However, a timeline can have repetitions, so a more accurate description of the</span></div>
<div style="position:absolute;left:5.00px;top:759.75px" class="cls_007"><span class="cls_007">Duration</span><span class="cls_004"> property might be that it specifies the time of a single iteration of the associated</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:182856px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background230.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_007"><span class="cls_007">Timeline</span><span class="cls_004"> object.</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">The duration property is of type </span><span class="cls_007">Duration</span><span class="cls_004">, which contains a </span><span class="cls_007">TimeSpan</span><span class="cls_004"> property that contains</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">the actual time that specifies the value of the duration. However, WPF includes a type</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">converter that enables us to specify this </span><span class="cls_007">TimeSpan</span><span class="cls_004"> value in XAML in the following formats,</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">where the square brackets highlight optional segments.</span></div>
<div style="position:absolute;left:52.98px;top:99.00px" class="cls_007"><span class="cls_007">Duration="[Days.]Hours:Minutes:Seconds[.FractionalSeconds]"</span></div>
<div style="position:absolute;left:52.98px;top:112.50px" class="cls_007"><span class="cls_007">Duration="[Days.]Hours:Minutes"</span></div>
<div style="position:absolute;left:5.00px;top:132.75px" class="cls_004"><span class="cls_004">However, the </span><span class="cls_007">Duration</span><span class="cls_004"> structure also accepts other values in addition to the </span><span class="cls_007">TimeSpan</span></div>
<div style="position:absolute;left:5.00px;top:150.75px" class="cls_004"><span class="cls_004">duration. There is a value of </span><span class="cls_007">Automatic</span><span class="cls_004">, which is the default value for component timelines</span></div>
<div style="position:absolute;left:5.00px;top:168.75px" class="cls_004"><span class="cls_004">that contain other timelines. In these cases, this value simply means that the parent</span></div>
<div style="position:absolute;left:5.00px;top:186.75px" class="cls_004"><span class="cls_004">timeline's duration will be as long as the longest duration of its children timelines. There is</span></div>
<div style="position:absolute;left:5.00px;top:204.75px" class="cls_004"><span class="cls_004">little purpose for us to explicitly use this value.</span></div>
<div style="position:absolute;left:5.00px;top:222.75px" class="cls_004"><span class="cls_004">However, there is one further value that is very useful to us. The </span><span class="cls_007">Duration</span><span class="cls_004"> structure also</span></div>
<div style="position:absolute;left:5.00px;top:240.75px" class="cls_004"><span class="cls_004">defines a </span><span class="cls_007">Forever</span><span class="cls_004"> property that represents an infinite period of time. We can use this value</span></div>
<div style="position:absolute;left:5.00px;top:258.75px" class="cls_004"><span class="cls_004">to make an animation continue indefinitely, or more accurately, as long as its related View is</span></div>
<div style="position:absolute;left:5.00px;top:276.75px" class="cls_004"><span class="cls_004">being displayed.</span></div>
<div style="position:absolute;left:52.98px;top:300.00px" class="cls_007"><span class="cls_007">Duration="Forever"</span></div>
<div style="position:absolute;left:5.00px;top:320.25px" class="cls_004"><span class="cls_004">A </span><span class="cls_007">Timeline</span><span class="cls_004"> object will stop playing when it reaches the end of its duration. If it has any child</span></div>
<div style="position:absolute;left:5.00px;top:338.25px" class="cls_004"><span class="cls_004">timelines associated with it, then they will also stop playing at this point. However, the</span></div>
<div style="position:absolute;left:5.00px;top:356.25px" class="cls_004"><span class="cls_004">natural duration of a timeline can be extended or shortened using other properties, as we</span></div>
<div style="position:absolute;left:5.00px;top:374.25px" class="cls_004"><span class="cls_004">will see shortly.</span></div>
<div style="position:absolute;left:5.00px;top:392.25px" class="cls_004"><span class="cls_004">Some timelines, such as the </span><span class="cls_007">ParallelTimeline</span><span class="cls_004"> and </span><span class="cls_007">Storyboard</span><span class="cls_004"> classes, are able to contain</span></div>
<div style="position:absolute;left:5.00px;top:410.25px" class="cls_004"><span class="cls_004">other timelines and can affect their durations by setting their own values for the </span><span class="cls_007">Duration</span></div>
<div style="position:absolute;left:5.00px;top:428.25px" class="cls_004"><span class="cls_004">property, which will override those set by the child timelines. Let's alter an earlier animation</span></div>
<div style="position:absolute;left:5.00px;top:446.25px" class="cls_004"><span class="cls_004">example from the previous chapter to demonstrate this.</span></div>
<div style="position:absolute;left:52.98px;top:469.50px" class="cls_007"><span class="cls_007"><Rectangle Width="0" Height="0" Fill="Orange"></span></div>
<div style="position:absolute;left:67.97px;top:483.00px" class="cls_007"><span class="cls_007"><Rectangle.Triggers></span></div>
<div style="position:absolute;left:82.97px;top:496.50px" class="cls_007"><span class="cls_007"><EventTrigger RoutedEvent="Loaded"></span></div>
<div style="position:absolute;left:97.96px;top:510.00px" class="cls_007"><span class="cls_007"><BeginStoryboard></span></div>
<div style="position:absolute;left:112.96px;top:523.50px" class="cls_007"><span class="cls_007"><Storyboard Duration="0:0:2.5"></span></div>
<div style="position:absolute;left:127.95px;top:537.00px" class="cls_007"><span class="cls_007"><DoubleAnimation Storyboard.TargetProperty="Width"</span></div>
<div style="position:absolute;left:52.98px;top:550.50px" class="cls_007"><span class="cls_007">To="300.0"</span></div>
<div style="position:absolute;left:142.94px;top:564.00px" class="cls_007"><span class="cls_007">Duration="0:0:2.5" /></span></div>
<div style="position:absolute;left:127.95px;top:577.50px" class="cls_007"><span class="cls_007"><DoubleAnimation Storyboard.TargetProperty="Height"</span></div>
<div style="position:absolute;left:52.98px;top:591.00px" class="cls_007"><span class="cls_007">To="300.0"</span></div>
<div style="position:absolute;left:142.94px;top:604.50px" class="cls_007"><span class="cls_007">Duration="0:0:5" /></span></div>
<div style="position:absolute;left:112.96px;top:618.00px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:97.96px;top:631.50px" class="cls_007"><span class="cls_007"></BeginStoryboard></span></div>
<div style="position:absolute;left:82.97px;top:645.00px" class="cls_007"><span class="cls_007"></EventTrigger></span></div>
<div style="position:absolute;left:67.97px;top:658.50px" class="cls_007"><span class="cls_007"></Rectangle.Triggers></span></div>
<div style="position:absolute;left:52.98px;top:672.00px" class="cls_007"><span class="cls_007"></Rectangle></span></div>
<div style="position:absolute;left:5.00px;top:692.25px" class="cls_004"><span class="cls_004">In this preceding example, we have a </span><span class="cls_007">Rectangle</span><span class="cls_004"> object with its dimensions initially set to</span></div>
<div style="position:absolute;left:5.00px;top:710.25px" class="cls_004"><span class="cls_004">zero. The </span><span class="cls_007">Storyboard</span><span class="cls_004"> object contains two separate animation objects that will animate its</span></div>
<div style="position:absolute;left:5.00px;top:728.25px" class="cls_004"><span class="cls_004">dimensions from zero to three hundred pixels. The animation object that will animate the</span></div>
<div style="position:absolute;left:5.00px;top:746.25px" class="cls_004"><span class="cls_004">rectangle's width has a duration of two and a half seconds, while the animation object that</span></div>
<div style="position:absolute;left:5.00px;top:764.25px" class="cls_004"><span class="cls_004">will animate the height has a duration of five seconds.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:183658px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background231.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">However, the containing </span><span class="cls_007">Storyboard</span><span class="cls_004"> object has a duration of two and a half seconds and so</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">this will stop the timelines of the two child animation objects after two and a half seconds,</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">regardless of their declared durations. The result of this will be that after the animation is</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">complete, our </span><span class="cls_007">Rectangle</span><span class="cls_004"> object will appear as a rectangle, instead of a square with equal</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">height and width values.</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">If we had changed the duration of the storyboard to match that of the longer child</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">animation, or changed that animation duration to match that of the shorter child animation,</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">then our animated shape would end as a square, rather than as a rectangle.</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">Another way to adjust the assigned duration of an animation element is to set its</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_007"><span class="cls_007">AutoReverse</span><span class="cls_004"> property. In effect, setting this property to </span><span class="cls_007">true</span><span class="cls_004"> will usually double the length of</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">time that is specified by the </span><span class="cls_007">Duration</span><span class="cls_004"> property, as the timeline will play in reverse after it</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">has completed its normal forwards iteration. Let's alter the storyboard from the previous</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">example to demonstrate this.</span></div>
<div style="position:absolute;left:52.98px;top:243.00px" class="cls_007"><span class="cls_007"><Storyboard Duration="0:0:5"></span></div>
<div style="position:absolute;left:67.97px;top:256.50px" class="cls_007"><span class="cls_007"><DoubleAnimation Storyboard.TargetProperty="Width" To="300.0"</span></div>
<div style="position:absolute;left:82.97px;top:270.00px" class="cls_007"><span class="cls_007">Duration="0:0:2.5" AutoReverse="True" /></span></div>
<div style="position:absolute;left:67.97px;top:283.50px" class="cls_007"><span class="cls_007"><DoubleAnimation Storyboard.TargetProperty="Height" To="300.0"</span></div>
<div style="position:absolute;left:82.97px;top:297.00px" class="cls_007"><span class="cls_007">Duration="0:0:5" /></span></div>
<div style="position:absolute;left:52.98px;top:310.50px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:5.00px;top:330.75px" class="cls_004"><span class="cls_004">Now, both child timelines will have the same overall duration, as the first, previously shorter,</span></div>
<div style="position:absolute;left:5.00px;top:348.75px" class="cls_004"><span class="cls_004">timeline has effectively been doubled in length. However, this will result in the first timeline</span></div>
<div style="position:absolute;left:5.00px;top:366.75px" class="cls_004"><span class="cls_004">animating the width of the rectangle to three hundred pixels and then back to zero, so it will</span></div>
<div style="position:absolute;left:5.00px;top:384.75px" class="cls_004"><span class="cls_004">be invisible when the animations have completed. Also note that we had to set the parent</span></div>
<div style="position:absolute;left:5.00px;top:402.75px" class="cls_004"><span class="cls_004">storyboard duration to five seconds in order to see the difference in the child timelines.</span></div>
<div style="position:absolute;left:5.00px;top:420.75px" class="cls_004"><span class="cls_004">Note again that properties set on timelines that contain other timelines will affect the values</span></div>
<div style="position:absolute;left:5.00px;top:438.75px" class="cls_004"><span class="cls_004">of those properties on the child timelines. As such, setting the </span><span class="cls_007">AutoReverse</span><span class="cls_004"> property to </span><span class="cls_007">true</span></div>
<div style="position:absolute;left:5.00px;top:456.75px" class="cls_004"><span class="cls_004">on the parent timeline (the </span><span class="cls_007">Storyboard</span><span class="cls_004"> object) will double the total length of time that the</span></div>
<div style="position:absolute;left:5.00px;top:474.75px" class="cls_004"><span class="cls_004">child animations will run for; in our case, using the following example, the rectangle will now</span></div>
<div style="position:absolute;left:5.00px;top:492.75px" class="cls_004"><span class="cls_004">be animated for ten seconds in total.</span></div>
<div style="position:absolute;left:52.98px;top:516.00px" class="cls_007"><span class="cls_007"><Storyboard Duration="0:0:5" AutoReverse="True"></span></div>
<div style="position:absolute;left:67.97px;top:529.50px" class="cls_007"><span class="cls_007"><DoubleAnimation Storyboard.TargetProperty="Width" To="300.0"</span></div>
<div style="position:absolute;left:82.97px;top:543.00px" class="cls_007"><span class="cls_007">Duration="0:0:2.5" AutoReverse="True" /></span></div>
<div style="position:absolute;left:67.97px;top:556.50px" class="cls_007"><span class="cls_007"><DoubleAnimation Storyboard.TargetProperty="Height" To="300.0"</span></div>
<div style="position:absolute;left:82.97px;top:570.00px" class="cls_007"><span class="cls_007">Duration="0:0:5" /></span></div>
<div style="position:absolute;left:52.98px;top:583.50px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:5.00px;top:603.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">RepeatBehavior</span><span class="cls_004"> property is of type </span><span class="cls_007">RepeatBehavior</span><span class="cls_004"> and can also affect the overall</span></div>
<div style="position:absolute;left:5.00px;top:621.75px" class="cls_004"><span class="cls_004">duration of a timeline. Unlike the </span><span class="cls_007">AutoReverse</span><span class="cls_004"> property, it can also shorten the overall</span></div>
<div style="position:absolute;left:5.00px;top:639.75px" class="cls_004"><span class="cls_004">duration as well as lengthen it. Using the </span><span class="cls_007">RepeatBehavior</span><span class="cls_004"> property, we can specify the value</span></div>
<div style="position:absolute;left:5.00px;top:657.75px" class="cls_004"><span class="cls_004">in a number of ways using different behaviors.</span></div>
<div style="position:absolute;left:5.00px;top:675.75px" class="cls_004"><span class="cls_004">The most simple is to provide a count of how many times we would like to multiply the</span></div>
<div style="position:absolute;left:5.00px;top:693.75px" class="cls_004"><span class="cls_004">original duration of the timeline. A pre-existing XAML type converter enables us to set the</span></div>
<div style="position:absolute;left:5.00px;top:711.75px" class="cls_004"><span class="cls_004">repeat count in XAML by specifying an </span><span class="cls_007">x</span><span class="cls_004"> after the count, as can be seen in the following</span></div>
<div style="position:absolute;left:5.00px;top:729.75px" class="cls_004"><span class="cls_004">example. Note that we can also specify numbers with decimal places here, including values</span></div>
<div style="position:absolute;left:5.00px;top:747.75px" class="cls_004"><span class="cls_004">less than one.</span></div>
<div style="position:absolute;left:52.98px;top:771.00px" class="cls_007"><span class="cls_007"><Storyboard Duration="0:0:5" AutoReverse="True"</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:184460px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background232.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:3.00px" class="cls_007"><span class="cls_007">RepeatBehavior="2x"></span></div>
<div style="position:absolute;left:67.97px;top:16.50px" class="cls_007"><span class="cls_007"><DoubleAnimation Storyboard.TargetProperty="Width" To="300.0"</span></div>
<div style="position:absolute;left:82.97px;top:30.00px" class="cls_007"><span class="cls_007">Duration="0:0:2.5" AutoReverse="True" /></span></div>
<div style="position:absolute;left:67.97px;top:43.50px" class="cls_007"><span class="cls_007"><DoubleAnimation Storyboard.TargetProperty="Height" To="300.0"</span></div>
<div style="position:absolute;left:82.97px;top:57.00px" class="cls_007"><span class="cls_007">Duration="0:0:5" /></span></div>
<div style="position:absolute;left:52.98px;top:70.50px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:5.00px;top:90.75px" class="cls_004"><span class="cls_004">In this example, the normal duration would be five seconds, but the </span><span class="cls_007">AutoReverse</span><span class="cls_004"> property is</span></div>
<div style="position:absolute;left:5.00px;top:108.75px" class="cls_004"><span class="cls_004">set to </span><span class="cls_007">true</span><span class="cls_004"> and so that duration is doubled. However, the </span><span class="cls_007">RepeatBehavior</span><span class="cls_004"> property is set to</span></div>
<div style="position:absolute;left:5.00px;top:126.75px" class="cls_007"><span class="cls_007">2x</span><span class="cls_004"> and this will multiply the doubled ten seconds to twenty seconds. This value of two will</span></div>
<div style="position:absolute;left:5.00px;top:144.75px" class="cls_004"><span class="cls_004">be stored in the </span><span class="cls_007">Count</span><span class="cls_004"> property of the </span><span class="cls_007">RepeatBehavior</span><span class="cls_004"> structure.</span></div>
<div style="position:absolute;left:5.00px;top:162.75px" class="cls_004"><span class="cls_004">An alternative to using the count option is to simply set the duration that we would like the</span></div>
<div style="position:absolute;left:5.00px;top:180.75px" class="cls_004"><span class="cls_004">animation to last for. The same XAML syntax that is used to set the </span><span class="cls_007">Duration</span><span class="cls_004"> property can</span></div>
<div style="position:absolute;left:5.00px;top:198.75px" class="cls_004"><span class="cls_004">also be used to set the </span><span class="cls_007">RepeatBehavior</span><span class="cls_004"> property. Similarly, the </span><span class="cls_007">RepeatBehavior</span><span class="cls_004"> structure</span></div>
<div style="position:absolute;left:5.00px;top:216.75px" class="cls_004"><span class="cls_004">also defines a </span><span class="cls_007">Forever</span><span class="cls_004"> property that represents an infinite period of time and we can use</span></div>
<div style="position:absolute;left:5.00px;top:234.75px" class="cls_004"><span class="cls_004">this value to make an animation continue indefinitely.</span></div>
<div style="position:absolute;left:5.00px;top:252.75px" class="cls_004"><span class="cls_004">One further property that can affect the duration of an animation is the </span><span class="cls_007">SpeedRatio</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:5.00px;top:270.75px" class="cls_004"><span class="cls_004">This value is multiplied by the other related duration properties and so can both speed up</span></div>
<div style="position:absolute;left:5.00px;top:288.75px" class="cls_004"><span class="cls_004">and slow down the associated timeline. Let's update our example again to help to explain</span></div>
<div style="position:absolute;left:5.00px;top:306.75px" class="cls_004"><span class="cls_004">this property now.</span></div>
<div style="position:absolute;left:52.98px;top:330.00px" class="cls_007"><span class="cls_007"><Storyboard Duration="0:0:5" AutoReverse="True" SpeedRatio="0.5"></span></div>
<div style="position:absolute;left:67.97px;top:343.50px" class="cls_007"><span class="cls_007"><DoubleAnimation Storyboard.TargetProperty="Width" To="300.0"</span></div>
<div style="position:absolute;left:82.97px;top:357.00px" class="cls_007"><span class="cls_007">Duration="0:0:2.5" AutoReverse="True" /></span></div>
<div style="position:absolute;left:67.97px;top:370.50px" class="cls_007"><span class="cls_007"><DoubleAnimation Storyboard.TargetProperty="Height" To="300.0"</span></div>
<div style="position:absolute;left:82.97px;top:384.00px" class="cls_007"><span class="cls_007">Duration="0:0:5" SpeedRatio="2" /></span></div>
<div style="position:absolute;left:52.98px;top:397.50px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:5.00px;top:417.75px" class="cls_004"><span class="cls_004">Again, the normal duration here would be five seconds and the </span><span class="cls_007">AutoReverse</span><span class="cls_004"> property is set</span></div>
<div style="position:absolute;left:5.00px;top:435.75px" class="cls_004"><span class="cls_004">to </span><span class="cls_007">true</span><span class="cls_004">, so the duration is doubled. However, the </span><span class="cls_007">SpeedRatio</span><span class="cls_004"> property is set to </span><span class="cls_007">0.5</span><span class="cls_004"> and so</span></div>
<div style="position:absolute;left:5.00px;top:453.75px" class="cls_004"><span class="cls_004">the doubled duration is again doubled to twenty seconds. Note that a </span><span class="cls_007">SpeedRatio</span><span class="cls_004"> value of</span></div>
<div style="position:absolute;left:5.00px;top:471.75px" class="cls_007"><span class="cls_007">0.5</span><span class="cls_004"> represents half the normal speed and therefore twice the normal duration.</span></div>
<div style="position:absolute;left:5.00px;top:489.75px" class="cls_004"><span class="cls_004">The second child timeline also sets the </span><span class="cls_007">SpeedRatio</span><span class="cls_004"> property, but its is set to </span><span class="cls_007">2</span><span class="cls_004"> and so its</span></div>
<div style="position:absolute;left:5.00px;top:507.75px" class="cls_004"><span class="cls_004">speed is doubled and its duration halved. As its specified duration is twice that of its sibling</span></div>
<div style="position:absolute;left:5.00px;top:525.75px" class="cls_004"><span class="cls_004">timeline and its speed now twice as fast, this has the effect of re-synchronizing the two</span></div>
<div style="position:absolute;left:5.00px;top:543.75px" class="cls_004"><span class="cls_004">child animations, so that the two dimensions now grow together, as a square, rather than</span></div>
<div style="position:absolute;left:5.00px;top:561.75px" class="cls_004"><span class="cls_004">as a rectangle.</span></div>
<div style="position:absolute;left:5.00px;top:579.75px" class="cls_004"><span class="cls_004">There are two more speed-related properties that we can use to fine-tune our animations;</span></div>
<div style="position:absolute;left:5.00px;top:597.75px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">AccelerationRatio</span><span class="cls_004"> and </span><span class="cls_007">DecelerationRatio</span><span class="cls_004"> properties. These properties adjust the</span></div>
<div style="position:absolute;left:5.00px;top:615.75px" class="cls_004"><span class="cls_004">proportion of time that the related animation takes to speed up and slow down respectively.</span></div>
<div style="position:absolute;left:5.00px;top:633.75px" class="cls_004"><span class="cls_004">While this effect can be subtle at times, it can also give our animations that professional</span></div>
<div style="position:absolute;left:5.00px;top:651.75px" class="cls_004"><span class="cls_004">touch when used correctly.</span></div>
<div style="position:absolute;left:5.00px;top:669.75px" class="cls_004"><span class="cls_004">Acceptable values for both of these properties exist between zero and one. Furthermore, if</span></div>
<div style="position:absolute;left:5.00px;top:687.75px" class="cls_004"><span class="cls_004">both of these properties are used, then the total sum of their values must remain at or</span></div>
<div style="position:absolute;left:5.00px;top:705.75px" class="cls_004"><span class="cls_004">below one. Failure to do so will result in the following exception being thrown at runtime:</span></div>
<div style="position:absolute;left:52.98px;top:728.25px" class="cls_009"><span class="cls_009">The sum of AccelerationRatio and DecelerationRatio must be less</span></div>
<div style="position:absolute;left:52.98px;top:742.50px" class="cls_009"><span class="cls_009">than</span></div>
<div style="position:absolute;left:52.98px;top:756.75px" class="cls_009"><span class="cls_009">or equal to one.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:185262px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background233.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">Entering values out of the acceptable range on either of these properties will also result in</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">an error, although doing this will cause a compilation error instead.</span></div>
<div style="position:absolute;left:52.98px;top:45.00px" class="cls_009"><span class="cls_009">Property value must be between 0.0 and 1.0.</span></div>
<div style="position:absolute;left:5.00px;top:66.00px" class="cls_004"><span class="cls_004">Let's look at an example that highlights the difference between the different values of these</span></div>
<div style="position:absolute;left:5.00px;top:84.00px" class="cls_004"><span class="cls_004">two properties:</span></div>
<div style="position:absolute;left:52.98px;top:107.25px" class="cls_007"><span class="cls_007"><StackPanel Margin="20"></span></div>
<div style="position:absolute;left:67.97px;top:120.75px" class="cls_007"><span class="cls_007"><StackPanel.Triggers></span></div>
<div style="position:absolute;left:82.97px;top:134.25px" class="cls_007"><span class="cls_007"><EventTrigger RoutedEvent="Loaded"></span></div>
<div style="position:absolute;left:97.96px;top:147.75px" class="cls_007"><span class="cls_007"><BeginStoryboard></span></div>
<div style="position:absolute;left:112.96px;top:161.25px" class="cls_007"><span class="cls_007"><Storyboard RepeatBehavior="Forever" Duration="0:0:1.5"</span></div>
<div style="position:absolute;left:127.95px;top:174.75px" class="cls_007"><span class="cls_007">SpeedRatio="0.5" Storyboard.TargetProperty="Width"></span></div>
<div style="position:absolute;left:127.95px;top:188.25px" class="cls_007"><span class="cls_007"><DoubleAnimation Storyboard.TargetName="RectangleA"</span></div>
<div style="position:absolute;left:142.94px;top:201.75px" class="cls_007"><span class="cls_007">AccelerationRatio="1.0" From="0" To="300" /></span></div>
<div style="position:absolute;left:127.95px;top:215.25px" class="cls_007"><span class="cls_007"><DoubleAnimation Storyboard.TargetName="RectangleB"</span></div>
<div style="position:absolute;left:142.94px;top:228.75px" class="cls_007"><span class="cls_007">AccelerationRatio="0.8" DecelerationRatio="0.2"</span></div>
<div style="position:absolute;left:52.98px;top:242.25px" class="cls_007"><span class="cls_007">From="0"</span></div>
<div style="position:absolute;left:142.94px;top:255.75px" class="cls_007"><span class="cls_007">To="300" /></span></div>
<div style="position:absolute;left:127.95px;top:269.25px" class="cls_007"><span class="cls_007"><DoubleAnimation Storyboard.TargetName="RectangleC"</span></div>
<div style="position:absolute;left:142.94px;top:282.75px" class="cls_007"><span class="cls_007">AccelerationRatio="0.6" DecelerationRatio="0.4"</span></div>
<div style="position:absolute;left:52.98px;top:296.25px" class="cls_007"><span class="cls_007">From="0"</span></div>
<div style="position:absolute;left:142.94px;top:309.75px" class="cls_007"><span class="cls_007">To="300" /></span></div>
<div style="position:absolute;left:127.95px;top:323.25px" class="cls_007"><span class="cls_007"><DoubleAnimation Storyboard.TargetName="RectangleD"</span></div>
<div style="position:absolute;left:142.94px;top:336.75px" class="cls_007"><span class="cls_007">AccelerationRatio="0.5" DecelerationRatio="0.5"</span></div>
<div style="position:absolute;left:52.98px;top:350.25px" class="cls_007"><span class="cls_007">From="0"</span></div>
<div style="position:absolute;left:142.94px;top:363.75px" class="cls_007"><span class="cls_007">To="300" /></span></div>
<div style="position:absolute;left:127.95px;top:377.25px" class="cls_007"><span class="cls_007"><DoubleAnimation Storyboard.TargetName="RectangleE"</span></div>
<div style="position:absolute;left:142.94px;top:390.75px" class="cls_007"><span class="cls_007">AccelerationRatio="0.4" DecelerationRatio="0.6"</span></div>
<div style="position:absolute;left:52.98px;top:404.25px" class="cls_007"><span class="cls_007">From="0"</span></div>
<div style="position:absolute;left:142.94px;top:417.75px" class="cls_007"><span class="cls_007">To="300" /></span></div>
<div style="position:absolute;left:127.95px;top:431.25px" class="cls_007"><span class="cls_007"><DoubleAnimation Storyboard.TargetName="RectangleF"</span></div>
<div style="position:absolute;left:142.94px;top:444.75px" class="cls_007"><span class="cls_007">AccelerationRatio="0.2" DecelerationRatio="0.8"</span></div>
<div style="position:absolute;left:52.98px;top:458.25px" class="cls_007"><span class="cls_007">From="0"</span></div>
<div style="position:absolute;left:142.94px;top:471.75px" class="cls_007"><span class="cls_007">To="300" /></span></div>
<div style="position:absolute;left:127.95px;top:485.25px" class="cls_007"><span class="cls_007"><DoubleAnimation Storyboard.TargetName="RectangleG"</span></div>
<div style="position:absolute;left:142.94px;top:498.75px" class="cls_007"><span class="cls_007">DecelerationRatio="1.0" From="0" To="300" /></span></div>
<div style="position:absolute;left:112.96px;top:512.25px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:97.96px;top:525.75px" class="cls_007"><span class="cls_007"></BeginStoryboard></span></div>
<div style="position:absolute;left:82.97px;top:539.25px" class="cls_007"><span class="cls_007"></EventTrigger></span></div>
<div style="position:absolute;left:67.97px;top:552.75px" class="cls_007"><span class="cls_007"></StackPanel.Triggers></span></div>
<div style="position:absolute;left:67.97px;top:566.25px" class="cls_007"><span class="cls_007"><Rectangle Name="RectangleA" Fill="#FF0000" Height="30" /></span></div>
<div style="position:absolute;left:67.97px;top:579.75px" class="cls_007"><span class="cls_007"><Rectangle Name="RectangleB" Fill="#D5002B" Height="30" /></span></div>
<div style="position:absolute;left:67.97px;top:593.25px" class="cls_007"><span class="cls_007"><Rectangle Name="RectangleC" Fill="#AB0055" Height="30" /></span></div>
<div style="position:absolute;left:67.97px;top:606.75px" class="cls_007"><span class="cls_007"><Rectangle Name="RectangleD" Fill="#800080" Height="30" /></span></div>
<div style="position:absolute;left:67.97px;top:620.25px" class="cls_007"><span class="cls_007"><Rectangle Name="RectangleE" Fill="#5500AB" Height="30" /></span></div>
<div style="position:absolute;left:67.97px;top:633.75px" class="cls_007"><span class="cls_007"><Rectangle Name="RectangleF" Fill="#2B00D5" Height="30" /></span></div>
<div style="position:absolute;left:67.97px;top:647.25px" class="cls_007"><span class="cls_007"><Rectangle Name="RectangleG" Fill="#0000FF" Height="30" /></span></div>
<div style="position:absolute;left:52.98px;top:660.75px" class="cls_007"><span class="cls_007"></StackPanel></span></div>
<div style="position:absolute;left:5.00px;top:681.00px" class="cls_004"><span class="cls_004">This code defines a number of </span><span class="cls_007">Rectangle</span><span class="cls_004"> objects in a </span><span class="cls_007">StackPanel</span><span class="cls_004"> control, each with its own</span></div>
<div style="position:absolute;left:5.00px;top:699.00px" class="cls_004"><span class="cls_004">associated </span><span class="cls_007">DoubleAnimation</span><span class="cls_004"> element, that increases its width from zero to three hundred</span></div>
<div style="position:absolute;left:5.00px;top:717.00px" class="cls_004"><span class="cls_004">pixels over one and a half seconds.</span></div>
<div style="position:absolute;left:5.00px;top:735.00px" class="cls_004"><span class="cls_004">Here, we've used the </span><span class="cls_007">Storyboard.TargetN</span><span class="cls_004"> </span><span class="cls_007">ame</span><span class="cls_004"> and </span><span class="cls_007">Storyboard.TargetProperty</span><span class="cls_004"> properties</span></div>
<div style="position:absolute;left:5.00px;top:753.00px" class="cls_004"><span class="cls_004">to target the rectangles from a single </span><span class="cls_007">EventTrigger</span><span class="cls_004"> to reduce the amount of code in the</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:186064px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background234.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">preceding example. We'll cover these Attached Properties in detail shortly, but for now, we'll</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">just say that they are used to specify the target element and property to animate.</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">Each animation targets a different rectangle and has different values set for the</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_007"><span class="cls_007">AccelerationRatio</span><span class="cls_004"> and </span><span class="cls_007">DecelerationRatio</span><span class="cls_004"> properties. The top rectangle's animation has</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">its </span><span class="cls_007">AccelerationRatio</span><span class="cls_004"> property set to </span><span class="cls_007">1.0</span><span class="cls_004"> and the animation for the bottom rectangle has</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">its </span><span class="cls_007">DecelerationRatio</span><span class="cls_004"> property set to </span><span class="cls_007">1.0</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">The animations for the rectangles in between have varying values. The higher the rectangle,</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">the higher the values for the </span><span class="cls_007">AccelerationRatio</span><span class="cls_004"> property and the lower the values for the</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_007"><span class="cls_007">DecelerationRatio</span><span class="cls_004"> property and the lower the rectangle, the lower the values of the</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_007"><span class="cls_007">AccelerationRatio</span><span class="cls_004"> property and the higher the values for the </span><span class="cls_007">DecelerationRatio</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">When this example is run, we can clearly see the differences between the various ratio</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">values. At one point near the start of each iteration, we can see that the top rectangles that</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">are animated with higher </span><span class="cls_007">AccelerationRatio</span><span class="cls_004"> values have not grown in size as much as the</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">lower rectangles that are animated with higher </span><span class="cls_007">DecelerationRatio</span><span class="cls_004"> values however, all</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">rectangles reach 300 pixels at approximately the same time.</span></div>
<div style="position:absolute;left:5.00px;top:534.00px" class="cls_004"><span class="cls_004">Another useful property in the </span><span class="cls_007">Timeline</span><span class="cls_004"> class is the </span><span class="cls_007">BeginTime</span><span class="cls_004"> property. As the name</span></div>
<div style="position:absolute;left:5.00px;top:552.00px" class="cls_004"><span class="cls_004">suggests, it sets the time to begin the animation; it can be thought of as a delay time that</span></div>
<div style="position:absolute;left:5.00px;top:570.00px" class="cls_004"><span class="cls_004">delays the start of its animation with relation to parent and sibling timelines.</span></div>
<div style="position:absolute;left:5.00px;top:588.00px" class="cls_004"><span class="cls_004">The default value of this property is zero seconds and when it is set with a positive value,</span></div>
<div style="position:absolute;left:5.00px;top:606.00px" class="cls_004"><span class="cls_004">the delay occurs just once at the start of the timeline and is not affected by other properties</span></div>
<div style="position:absolute;left:5.00px;top:624.00px" class="cls_004"><span class="cls_004">that may be set on it. It is often used to delay the start of one or more animations until</span></div>
<div style="position:absolute;left:5.00px;top:642.00px" class="cls_004"><span class="cls_004">another animation has completed. Let's adjust our earlier example again to demonstrate</span></div>
<div style="position:absolute;left:5.00px;top:660.00px" class="cls_004"><span class="cls_004">this.</span></div>
<div style="position:absolute;left:52.98px;top:683.25px" class="cls_007"><span class="cls_007"><Rectangle Width="0" Height="1" Fill="Orange"></span></div>
<div style="position:absolute;left:67.97px;top:696.75px" class="cls_007"><span class="cls_007"><Rectangle.Triggers></span></div>
<div style="position:absolute;left:82.97px;top:710.25px" class="cls_007"><span class="cls_007"><EventTrigger RoutedEvent="Loaded"></span></div>
<div style="position:absolute;left:97.96px;top:723.75px" class="cls_007"><span class="cls_007"><BeginStoryboard></span></div>
<div style="position:absolute;left:112.96px;top:737.25px" class="cls_007"><span class="cls_007"><Storyboard></span></div>
<div style="position:absolute;left:127.95px;top:750.75px" class="cls_007"><span class="cls_007"><DoubleAnimation Storyboard.TargetProperty="Width"</span></div>
<div style="position:absolute;left:52.98px;top:764.25px" class="cls_007"><span class="cls_007">To="300.0"</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:186866px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background235.jpg" width=612 height=792></div>
<div style="position:absolute;left:142.94px;top:3.00px" class="cls_007"><span class="cls_007">Duration="0:0:2" /></span></div>
<div style="position:absolute;left:127.95px;top:16.50px" class="cls_007"><span class="cls_007"><DoubleAnimation Storyboard.TargetProperty="Height"</span></div>
<div style="position:absolute;left:52.98px;top:30.00px" class="cls_007"><span class="cls_007">To="300.0"</span></div>
<div style="position:absolute;left:142.94px;top:43.50px" class="cls_007"><span class="cls_007">Duration="0:0:2" BeginTime="0:0:2" /></span></div>
<div style="position:absolute;left:127.95px;top:57.00px" class="cls_007"><span class="cls_007"><DoubleAnimation Storyboard.TargetProperty="Width"</span></div>
<div style="position:absolute;left:52.98px;top:70.50px" class="cls_007"><span class="cls_007">To="0.0"</span></div>
<div style="position:absolute;left:142.94px;top:84.00px" class="cls_007"><span class="cls_007">Duration="0:0:2" BeginTime="0:0:4" /></span></div>
<div style="position:absolute;left:127.95px;top:97.50px" class="cls_007"><span class="cls_007"><DoubleAnimation Storyboard.TargetProperty="Height"</span></div>
<div style="position:absolute;left:52.98px;top:111.00px" class="cls_007"><span class="cls_007">To="0.0"</span></div>
<div style="position:absolute;left:142.94px;top:124.50px" class="cls_007"><span class="cls_007">Duration="0:0:2" BeginTime="0:0:4" /></span></div>
<div style="position:absolute;left:112.96px;top:138.00px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:97.96px;top:151.50px" class="cls_007"><span class="cls_007"></BeginStoryboard></span></div>
<div style="position:absolute;left:82.97px;top:165.00px" class="cls_007"><span class="cls_007"></EventTrigger></span></div>
<div style="position:absolute;left:67.97px;top:178.50px" class="cls_007"><span class="cls_007"></Rectangle.Triggers></span></div>
<div style="position:absolute;left:52.98px;top:192.00px" class="cls_007"><span class="cls_007"></Rectangle></span></div>
<div style="position:absolute;left:5.00px;top:212.25px" class="cls_004"><span class="cls_004">In this example, we have a single pixel high rectangle with a width that grows outward until</span></div>
<div style="position:absolute;left:5.00px;top:230.25px" class="cls_004"><span class="cls_004">it is three hundred pixels wide and then grows vertically until it is three hundred pixels high.</span></div>
<div style="position:absolute;left:5.00px;top:248.25px" class="cls_004"><span class="cls_004">At that point, its dimensions equally reduce in size until the shape shrinks to nothing.</span></div>
<div style="position:absolute;left:5.00px;top:266.25px" class="cls_004"><span class="cls_004">This is achieved by delaying the last three animations while the width-increasing animation</span></div>
<div style="position:absolute;left:5.00px;top:284.25px" class="cls_004"><span class="cls_004">runs and then delaying the last two animations while the height-increasing animation runs.</span></div>
<div style="position:absolute;left:5.00px;top:302.25px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">BeginTime</span><span class="cls_004"> properties of the last two animations are set to the same value, so that they</span></div>
<div style="position:absolute;left:5.00px;top:320.25px" class="cls_004"><span class="cls_004">both start and run in synchronization with each other.</span></div>
<div style="position:absolute;left:5.00px;top:338.25px" class="cls_004"><span class="cls_004">The last really useful timeline property is the </span><span class="cls_007">FillBehavior</span><span class="cls_004"> property, which specifies what</span></div>
<div style="position:absolute;left:5.00px;top:356.25px" class="cls_004"><span class="cls_004">should happen to the data bound property value when the timeline reaches the end of its</span></div>
<div style="position:absolute;left:5.00px;top:374.25px" class="cls_004"><span class="cls_004">total duration, or its fill period. This property is of type </span><span class="cls_007">FillBehavior</span><span class="cls_004"> and has just two</span></div>
<div style="position:absolute;left:5.00px;top:392.25px" class="cls_004"><span class="cls_004">values.</span></div>
<div style="position:absolute;left:5.00px;top:410.25px" class="cls_004"><span class="cls_004">If we set this property to a value of </span><span class="cls_007">HoldEnd</span><span class="cls_004">, the data bound property value will remain at</span></div>
<div style="position:absolute;left:5.00px;top:428.25px" class="cls_004"><span class="cls_004">the final value that was reached just before the animation ended. Conversely, if we set this</span></div>
<div style="position:absolute;left:5.00px;top:446.25px" class="cls_004"><span class="cls_004">property to a value of </span><span class="cls_007">Stop</span><span class="cls_004">, which is the default value, the data bound property value will</span></div>
<div style="position:absolute;left:5.00px;top:464.25px" class="cls_004"><span class="cls_004">revert to the value that the property originally had before the animation started. Let's</span></div>
<div style="position:absolute;left:5.00px;top:482.25px" class="cls_004"><span class="cls_004">illustrate this with a simple example.</span></div>
<div style="position:absolute;left:52.98px;top:505.50px" class="cls_007"><span class="cls_007"><StackPanel Margin="20"></span></div>
<div style="position:absolute;left:67.97px;top:519.00px" class="cls_007"><span class="cls_007"><StackPanel.Triggers></span></div>
<div style="position:absolute;left:82.97px;top:532.50px" class="cls_007"><span class="cls_007"><EventTrigger RoutedEvent="Loaded"></span></div>
<div style="position:absolute;left:97.96px;top:546.00px" class="cls_007"><span class="cls_007"><BeginStoryboard></span></div>
<div style="position:absolute;left:112.96px;top:559.50px" class="cls_007"><span class="cls_007"><Storyboard Duration="0:0:1.5" SpeedRatio="0.5"</span></div>
<div style="position:absolute;left:127.95px;top:573.00px" class="cls_007"><span class="cls_007">Storyboard.TargetProperty="Opacity"></span></div>
<div style="position:absolute;left:127.95px;top:586.50px" class="cls_007"><span class="cls_007"><DoubleAnimation Storyboard.TargetName="RectangleA"</span></div>
<div style="position:absolute;left:52.98px;top:600.00px" class="cls_007"><span class="cls_007">To="0.0"</span></div>
<div style="position:absolute;left:142.94px;top:613.50px" class="cls_007"><span class="cls_007">FillBehavior="HoldEnd" /></span></div>
<div style="position:absolute;left:127.95px;top:627.00px" class="cls_007"><span class="cls_007"><DoubleAnimation Storyboard.TargetName="RectangleB"</span></div>
<div style="position:absolute;left:52.98px;top:640.50px" class="cls_007"><span class="cls_007">To="0.0"</span></div>
<div style="position:absolute;left:142.94px;top:654.00px" class="cls_007"><span class="cls_007">FillBehavior="Stop" /></span></div>
<div style="position:absolute;left:112.96px;top:667.50px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:97.96px;top:681.00px" class="cls_007"><span class="cls_007"></BeginStoryboard></span></div>
<div style="position:absolute;left:82.97px;top:694.50px" class="cls_007"><span class="cls_007"></EventTrigger></span></div>
<div style="position:absolute;left:67.97px;top:708.00px" class="cls_007"><span class="cls_007"></StackPanel.Triggers></span></div>
<div style="position:absolute;left:67.97px;top:721.50px" class="cls_007"><span class="cls_007"><Rectangle Name="RectangleA" Fill="Orange" Height="100"</span></div>
<div style="position:absolute;left:82.97px;top:735.00px" class="cls_007"><span class="cls_007">HorizontalAlignment="Stretch" Margin="0,0,0,20" /></span></div>
<div style="position:absolute;left:67.97px;top:748.50px" class="cls_007"><span class="cls_007"><Rectangle Name="RectangleB" Fill="Orange" Height="100"</span></div>
<div style="position:absolute;left:82.97px;top:762.00px" class="cls_007"><span class="cls_007">HorizontalAlignment="Stretch" /></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:187668px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background236.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:3.00px" class="cls_007"><span class="cls_007"></StackPanel></span></div>
<div style="position:absolute;left:5.00px;top:23.25px" class="cls_004"><span class="cls_004">In this example, the difference between the two </span><span class="cls_007">FillBehavior</span><span class="cls_004"> enumeration instances is</span></div>
<div style="position:absolute;left:5.00px;top:41.25px" class="cls_004"><span class="cls_004">clearly demonstrated. We have two rectangles of identical size that have identical timelines</span></div>
<div style="position:absolute;left:5.00px;top:59.25px" class="cls_004"><span class="cls_004">set up to animate their </span><span class="cls_007">Opacity</span><span class="cls_004"> property values, with the exception of their </span><span class="cls_007">FillBehavior</span></div>
<div style="position:absolute;left:5.00px;top:77.25px" class="cls_004"><span class="cls_004">property values.</span></div>
<div style="position:absolute;left:5.00px;top:95.25px" class="cls_004"><span class="cls_004">Both rectangles fade from being opaque to being invisible in the same amount of time, but</span></div>
<div style="position:absolute;left:5.00px;top:113.25px" class="cls_004"><span class="cls_004">once the two timelines are complete, the rectangle with the </span><span class="cls_007">FillBehavior</span><span class="cls_004"> property set to</span></div>
<div style="position:absolute;left:5.00px;top:131.25px" class="cls_007"><span class="cls_007">Stop</span><span class="cls_004"> immediately becomes visible again, as it was prior to the start of the animation, while</span></div>
<div style="position:absolute;left:5.00px;top:149.25px" class="cls_004"><span class="cls_004">the other with the </span><span class="cls_007">FillBehavior</span><span class="cls_004"> property set to </span><span class="cls_007">HoldEnd</span><span class="cls_004"> remains invisible, as it was at the</span></div>
<div style="position:absolute;left:5.00px;top:167.25px" class="cls_004"><span class="cls_004">end of the animation.</span></div>
<div style="position:absolute;left:5.00px;top:185.25px" class="cls_004"><span class="cls_004">While this covers the main properties that are exposed by the </span><span class="cls_007">Timeline</span><span class="cls_004"> class directly, there</span></div>
<div style="position:absolute;left:5.00px;top:203.25px" class="cls_004"><span class="cls_004">are a few more properties that are declared by many of the animation classes that extend</span></div>
<div style="position:absolute;left:5.00px;top:221.25px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">Timeline</span><span class="cls_004"> class and are essential to fully understand. They are the </span><span class="cls_007">From</span><span class="cls_004">, </span><span class="cls_007">By</span><span class="cls_004"> and </span><span class="cls_007">To</span></div>
<div style="position:absolute;left:5.00px;top:239.25px" class="cls_004"><span class="cls_004">properties, which specify the start and end points of the animations.</span></div>
<div style="position:absolute;left:5.00px;top:257.25px" class="cls_004"><span class="cls_004">Because the animation classes generate property values, there are different types of</span></div>
<div style="position:absolute;left:5.00px;top:275.25px" class="cls_004"><span class="cls_004">animation classes for different property types. For example, the animation class that</span></div>
<div style="position:absolute;left:5.00px;top:293.25px" class="cls_004"><span class="cls_004">generates </span><span class="cls_007">Point</span><span class="cls_004"> values is called the </span><span class="cls_007">PointAnimation</span><span class="cls_004"> class and all of the normal animation</span></div>
<div style="position:absolute;left:5.00px;top:311.25px" class="cls_004"><span class="cls_004">classes follow the same naming pattern, using the name of the related type in the form</span></div>
<div style="position:absolute;left:5.00px;top:329.25px" class="cls_007"><span class="cls_007"><TypeName>Animation</span><span class="cls_004">, for example </span><span class="cls_007">ColorAnimation</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:347.25px" class="cls_004"><span class="cls_004">The normal animation classes, often referred to as the </span><span class="cls_007">From</span><span class="cls_004">, </span><span class="cls_007">By</span><span class="cls_004"> and </span><span class="cls_007">To</span><span class="cls_004"> animations, usually</span></div>
<div style="position:absolute;left:5.00px;top:365.25px" class="cls_004"><span class="cls_004">require two values to be specified, although one of these can sometimes be implicitly</span></div>
<div style="position:absolute;left:5.00px;top:383.25px" class="cls_004"><span class="cls_004">provided. The relevant property will then be animated along a path of automatically</span></div>
<div style="position:absolute;left:5.00px;top:401.25px" class="cls_004"><span class="cls_004">interpolated values between the two specified values.</span></div>
<div style="position:absolute;left:5.00px;top:419.25px" class="cls_004"><span class="cls_004">It is most common to provide a starting value using the </span><span class="cls_007">From</span><span class="cls_004"> property and an ending value</span></div>
<div style="position:absolute;left:5.00px;top:437.25px" class="cls_004"><span class="cls_004">using the </span><span class="cls_007">To</span><span class="cls_004"> property. However, we can also specify a single starting, ending, or offset</span></div>
<div style="position:absolute;left:5.00px;top:455.25px" class="cls_004"><span class="cls_004">value and the second value will be taken from the current value of the animated property.</span></div>
<div style="position:absolute;left:5.00px;top:473.25px" class="cls_004"><span class="cls_004">We can set the offset value using the </span><span class="cls_007">By</span><span class="cls_004"> property and this represents the exact amount the</span></div>
<div style="position:absolute;left:5.00px;top:491.25px" class="cls_004"><span class="cls_004">property value will change over the duration.</span></div>
<div style="position:absolute;left:5.00px;top:509.25px" class="cls_004"><span class="cls_004">Specifying values for these different properties can have dramatically different effects on</span></div>
<div style="position:absolute;left:5.00px;top:527.25px" class="cls_004"><span class="cls_004">the resulting animations. Using the </span><span class="cls_007">From</span><span class="cls_004"> property alone will start the animation at the</span></div>
<div style="position:absolute;left:5.00px;top:545.25px" class="cls_004"><span class="cls_004">desired value and will animate the property until it reaches the property's base value.</span></div>
<div style="position:absolute;left:5.00px;top:563.25px" class="cls_004"><span class="cls_004">Using the </span><span class="cls_007">To</span><span class="cls_004"> property alone will start animating the property from its current value and end</span></div>
<div style="position:absolute;left:5.00px;top:581.25px" class="cls_004"><span class="cls_004">at the specified value. Using only the </span><span class="cls_007">By</span><span class="cls_004"> property will animate the property from its current</span></div>
<div style="position:absolute;left:5.00px;top:599.25px" class="cls_004"><span class="cls_004">value until the sum of that value with the specified offset amount has been reached.</span></div>
<div style="position:absolute;left:5.00px;top:617.25px" class="cls_004"><span class="cls_004">Combinations of the three properties can be used to target just the right range of property</span></div>
<div style="position:absolute;left:5.00px;top:635.25px" class="cls_004"><span class="cls_004">values. Setting the </span><span class="cls_007">From</span><span class="cls_004"> and </span><span class="cls_007">By</span><span class="cls_004"> properties will start the animations from the value specified</span></div>
<div style="position:absolute;left:5.00px;top:653.25px" class="cls_004"><span class="cls_004">by the </span><span class="cls_007">From</span><span class="cls_004"> property and animate the property until the offset specified by the </span><span class="cls_007">By</span><span class="cls_004"> property</span></div>
<div style="position:absolute;left:5.00px;top:671.25px" class="cls_004"><span class="cls_004">has been reached.</span></div>
<div style="position:absolute;left:5.00px;top:689.25px" class="cls_004"><span class="cls_004">Setting the </span><span class="cls_007">From</span><span class="cls_004"> and </span><span class="cls_007">To</span><span class="cls_004"> properties together will start the animations from the value specified</span></div>
<div style="position:absolute;left:5.00px;top:707.25px" class="cls_004"><span class="cls_004">by the </span><span class="cls_007">From</span><span class="cls_004"> property and animate the property until the value specified by the </span><span class="cls_007">To</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:5.00px;top:725.25px" class="cls_004"><span class="cls_004">As the </span><span class="cls_007">By</span><span class="cls_004"> and </span><span class="cls_007">To</span><span class="cls_004"> properties both specify the ending value of the animation, the value</span></div>
<div style="position:absolute;left:5.00px;top:743.25px" class="cls_004"><span class="cls_004">specified by the </span><span class="cls_007">By</span><span class="cls_004"> property will be ignored if they are both set on an animation element.</span></div>
<div style="position:absolute;left:5.00px;top:761.25px" class="cls_004"><span class="cls_004">While these more common animations use one or two of the </span><span class="cls_007">From</span><span class="cls_004">, </span><span class="cls_007">By</span><span class="cls_004">, and </span><span class="cls_007">To</span><span class="cls_004"> properties</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:188470px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background237.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">together to specify the range of values of the related property to be animated, there is</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">another way to specify the target values. Let's now take a look at key-frame animations.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:189272px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background238.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_008"><span class="cls_008">Introducing key-frames</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">Key-frame animations enable us to do a number of things that we cannot do with the </span><span class="cls_007">From</span><span class="cls_004">,</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_007"><span class="cls_007">By</span><span class="cls_004">, and </span><span class="cls_007">To</span><span class="cls_004"> animations. Unlike those animations, with key-frame animations, we are able to</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">specify more than two target values and animate objects in discrete steps that cannot</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">normally be animated. As such, there are more </span><span class="cls_007"><TypeName>AnimationUsingKeyFrames</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">classes than </span><span class="cls_007"><TypeName>Animation</span><span class="cls_004"> classes, for example: </span><span class="cls_007">RectAnimationUsingKeyFrames</span><span class="cls_004">,</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_007"><span class="cls_007">SizeAnimationUsingKeyFrames</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">Each </span><span class="cls_007"><TypeName>AnimationUsingKeyFrames</span><span class="cls_004"> class has a </span><span class="cls_007">KeyFrames</span><span class="cls_004"> property that we</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">populate with key-frames to specify various values that must be passed during the</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">animation. Each key-frame has a </span><span class="cls_007">KeyTime</span><span class="cls_004"> and a </span><span class="cls_007">Value</span><span class="cls_004"> property to specify the value and the</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">relative time that it should be reached.</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">If no key-frame is declared with a key time of zero seconds, the animation will start from</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">the relevant property's current value. The animation will order the key-frames by the values</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">of their </span><span class="cls_007">KeyTime</span><span class="cls_004"> property, rather than the order that they were declared in, and will create</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">transitions between the various values according to their interpolation methods, which we'll</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">find out about momentarily.</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">Note that the </span><span class="cls_007">KeyTime</span><span class="cls_004"> property is of type </span><span class="cls_007">KeyTime</span><span class="cls_004"> and this enables us to set it using types</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_004"><span class="cls_004">of values, other than </span><span class="cls_007">TimeSpan</span><span class="cls_004"> values. We are also able to specify percentage values,</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_004"><span class="cls_004">which determine the percentage of the specified animation duration that each key-frame will</span></div>
<div style="position:absolute;left:5.00px;top:363.75px" class="cls_004"><span class="cls_004">be allotted. Note that we need to use cumulative values, so that the final key-frame key</span></div>
<div style="position:absolute;left:5.00px;top:381.75px" class="cls_004"><span class="cls_004">time value will always be </span><span class="cls_007">100%</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:399.75px" class="cls_004"><span class="cls_004">Alternatively, there are a number of special values that we can use. When we want an</span></div>
<div style="position:absolute;left:5.00px;top:417.75px" class="cls_004"><span class="cls_004">animation with a constant velocity, regardless of the specified values, we can specify the</span></div>
<div style="position:absolute;left:5.00px;top:435.75px" class="cls_007"><span class="cls_007">Paced</span><span class="cls_004"> value for each of the key-frames. This takes the change between each key-frame's</span></div>
<div style="position:absolute;left:5.00px;top:453.75px" class="cls_004"><span class="cls_004">value into consideration before spacing them across the duration of the parent timeline and</span></div>
<div style="position:absolute;left:5.00px;top:471.75px" class="cls_004"><span class="cls_004">creating a smooth, even transition.</span></div>
<div style="position:absolute;left:5.00px;top:489.75px" class="cls_004"><span class="cls_004">In contrast to this method, we can also specify the </span><span class="cls_007">Uniform</span><span class="cls_004"> value for each key-frame, which</span></div>
<div style="position:absolute;left:5.00px;top:507.75px" class="cls_004"><span class="cls_004">basically spaces the key-frames out evenly across the duration of the parent animation. To</span></div>
<div style="position:absolute;left:5.00px;top:525.75px" class="cls_004"><span class="cls_004">do this, it simply counts the number of key-frames and divides that number by the total</span></div>
<div style="position:absolute;left:5.00px;top:543.75px" class="cls_004"><span class="cls_004">duration length, so that each key-frame will last for the same amount of time.</span></div>
<div style="position:absolute;left:5.00px;top:561.75px" class="cls_004"><span class="cls_004">There are different kinds of key-frames for different </span><span class="cls_007"><TypeName>AnimationUsingKeyFrames</span></div>
<div style="position:absolute;left:5.00px;top:579.75px" class="cls_004"><span class="cls_004">classes and there are also different kinds of interpolation methods used. The naming</span></div>
<div style="position:absolute;left:5.00px;top:597.75px" class="cls_004"><span class="cls_004">convention of these key-frames follows the format, </span><span class="cls_007"><InterpolationMethod></span></div>
<div style="position:absolute;left:5.00px;top:615.75px" class="cls_007"><span class="cls_007"><TypeName>KeyFrame</span><span class="cls_004">, for example: </span><span class="cls_007">LinearDoubleKeyFrame</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:633.75px" class="cls_004"><span class="cls_004">There are three kinds of interpolation methods. The first is </span><span class="cls_007">Discrete</span><span class="cls_004">, which performs no</span></div>
<div style="position:absolute;left:5.00px;top:651.75px" class="cls_004"><span class="cls_004">interpolation and simply jumps from one value to another. This method is useful for setting</span></div>
<div style="position:absolute;left:5.00px;top:669.75px" class="cls_004"><span class="cls_004">Boolean or object values.</span></div>
<div style="position:absolute;left:5.00px;top:687.75px" class="cls_004"><span class="cls_004">The next method is </span><span class="cls_007">Linear</span><span class="cls_004">, which performs a linear interpolation between the key-frame's</span></div>
<div style="position:absolute;left:5.00px;top:705.75px" class="cls_004"><span class="cls_004">value and the previous key-frame's value. This means that the animation will appear</span></div>
<div style="position:absolute;left:5.00px;top:723.75px" class="cls_004"><span class="cls_004">smooth, but speed up and slow down if your key-frame times are not evenly spaced out.</span></div>
<div style="position:absolute;left:5.00px;top:741.75px" class="cls_004"><span class="cls_004">The last and most complicated interpolation method is </span><span class="cls_007">Spline</span><span class="cls_004">, but it also provides the user</span></div>
<div style="position:absolute;left:5.00px;top:759.75px" class="cls_004"><span class="cls_004">with the most control over the animation timing. It adds a further property named</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:190074px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background239.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_007"><span class="cls_007">KeySpline</span><span class="cls_004">, which enables us to specify two control points on a Bezier curve that extends</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">from </span><span class="cls_007">0.0</span><span class="cls_004">, </span><span class="cls_007">0.0</span><span class="cls_004"> to </span><span class="cls_007">1.0</span><span class="cls_004">, </span><span class="cls_007">1.0</span><span class="cls_004">. The first control point affects the first half of the curve, while the</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">second point affects the second half.</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">Using these two control points, we can adjust the speed of the animation over its duration.</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">As an example, using the first control point set to </span><span class="cls_007">0.0</span><span class="cls_004">, </span><span class="cls_007">1,0</span><span class="cls_004"> and the second set to </span><span class="cls_007">1.0</span><span class="cls_004">, </span><span class="cls_007">0.0</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">will cause maximum distortion to the original linear curve and result in an animation that will</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">quickly accelerate, before slowing almost to a stop in the middle and then dramatically</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">speeding up again at the end.</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">With these two points, we can have full control over the speed of value change between</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">each pair of key-frame values. This type of interpolation is most useful when attempting to</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">create animations that are more realistic looking. Note that we are free to mix and match</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">key-frames with different interpolation methods within each key-frame animation.</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">As an example, let's say that we wanted to animate a </span><span class="cls_007">Point</span><span class="cls_004"> element. In this case we'd</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">need to use the </span><span class="cls_007">PointAnimationUsingKeyFrames</span><span class="cls_004"> class and would then have a choice of</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">key-frame classes that represent the different interpolation methods. With this example, we</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">could use any combination of the </span><span class="cls_007">DiscretePointKeyFrame</span><span class="cls_004">, </span><span class="cls_007">LinearPointKeyFrame</span><span class="cls_004">, and</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_007"><span class="cls_007">SplinePointKeyFrame</span><span class="cls_004"> classes.</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">Note that, as the </span><span class="cls_007">KeyFrames</span><span class="cls_004"> property is set as the </span><span class="cls_007">name</span><span class="cls_004"> input parameter in the</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_007"><span class="cls_007">ContentPropertyAttribute</span><span class="cls_004"> attribute that forms part of the declared class signature in each</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_004"><span class="cls_004">of the </span><span class="cls_007"><TypeName>AnimationUsingKeyFrames</span><span class="cls_004"> classes, we do not need to explicitly declare</span></div>
<div style="position:absolute;left:5.00px;top:363.75px" class="cls_004"><span class="cls_004">this property in XAML and can declare the various key-frames directly inside these</span></div>
<div style="position:absolute;left:5.00px;top:381.75px" class="cls_004"><span class="cls_004">elements as shown in the following code:</span></div>
<div style="position:absolute;left:52.98px;top:405.00px" class="cls_007"><span class="cls_007"><Ellipse Width="100" Height="100" Stroke="Black"</span></div>
<div style="position:absolute;left:52.98px;top:418.50px" class="cls_007"><span class="cls_007">StrokeThickness="3"></span></div>
<div style="position:absolute;left:67.97px;top:432.00px" class="cls_007"><span class="cls_007"><Ellipse.Fill></span></div>
<div style="position:absolute;left:82.97px;top:445.50px" class="cls_007"><span class="cls_007"><RadialGradientBrush></span></div>
<div style="position:absolute;left:97.96px;top:459.00px" class="cls_007"><span class="cls_007"><GradientStop Color="Yellow" Offset="0" /></span></div>
<div style="position:absolute;left:97.96px;top:472.50px" class="cls_007"><span class="cls_007"><GradientStop Color="Orange" Offset="1" /></span></div>
<div style="position:absolute;left:82.97px;top:486.00px" class="cls_007"><span class="cls_007"></RadialGradientBrush></span></div>
<div style="position:absolute;left:67.97px;top:499.50px" class="cls_007"><span class="cls_007"></Ellipse.Fill></span></div>
<div style="position:absolute;left:67.97px;top:513.00px" class="cls_007"><span class="cls_007"><Ellipse.Triggers></span></div>
<div style="position:absolute;left:82.97px;top:526.50px" class="cls_007"><span class="cls_007"><EventTrigger RoutedEvent="Loaded"></span></div>
<div style="position:absolute;left:97.96px;top:540.00px" class="cls_007"><span class="cls_007"><BeginStoryboard></span></div>
<div style="position:absolute;left:112.96px;top:553.50px" class="cls_007"><span class="cls_007"><Storyboard RepeatBehavior="Forever"</span></div>
<div style="position:absolute;left:127.95px;top:567.00px" class="cls_007"><span class="cls_007">Storyboard.TargetProperty="Fill.GradientOrigin"></span></div>
<div style="position:absolute;left:127.95px;top:580.50px" class="cls_007"><span class="cls_007"><PointAnimationUsingKeyFrames></span></div>
<div style="position:absolute;left:142.94px;top:594.00px" class="cls_007"><span class="cls_007"><DiscretePointKeyFrame Value="0.5, 0.5" KeyTime="0:0:0"</span></div>
<div style="position:absolute;left:52.98px;top:607.50px" class="cls_007"><span class="cls_007">/></span></div>
<div style="position:absolute;left:142.94px;top:621.00px" class="cls_007"><span class="cls_007"><LinearPointKeyFrame Value="1.0, 1.0" KeyTime="0:0:2"</span></div>
<div style="position:absolute;left:52.98px;top:634.50px" class="cls_007"><span class="cls_007">/></span></div>
<div style="position:absolute;left:142.94px;top:648.00px" class="cls_007"><span class="cls_007"><SplinePointKeyFrame KeySpline="0,0.25 0.75,0"</span></div>
<div style="position:absolute;left:52.98px;top:661.50px" class="cls_007"><span class="cls_007">Value="1.0, 0.0"</span></div>
<div style="position:absolute;left:157.94px;top:675.00px" class="cls_007"><span class="cls_007">KeyTime="0:0:4" /></span></div>
<div style="position:absolute;left:142.94px;top:688.50px" class="cls_007"><span class="cls_007"><LinearPointKeyFrame Value="0.0, 0.0" KeyTime="0:0:5"</span></div>
<div style="position:absolute;left:52.98px;top:702.00px" class="cls_007"><span class="cls_007">/></span></div>
<div style="position:absolute;left:142.94px;top:715.50px" class="cls_007"><span class="cls_007"><SplinePointKeyFrame KeySpline="0,0.75 0.25,0"</span></div>
<div style="position:absolute;left:52.98px;top:729.00px" class="cls_007"><span class="cls_007">Value="0.5, 0.5"</span></div>
<div style="position:absolute;left:157.94px;top:742.50px" class="cls_007"><span class="cls_007">KeyTime="0:0:8" /></span></div>
<div style="position:absolute;left:127.95px;top:756.00px" class="cls_007"><span class="cls_007"></PointAnimationUsingKeyFrames></span></div>
<div style="position:absolute;left:112.96px;top:769.50px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:190876px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background240.jpg" width=612 height=792></div>
<div style="position:absolute;left:97.96px;top:3.00px" class="cls_007"><span class="cls_007"></BeginStoryboard></span></div>
<div style="position:absolute;left:82.97px;top:16.50px" class="cls_007"><span class="cls_007"></EventTrigger></span></div>
<div style="position:absolute;left:67.97px;top:30.00px" class="cls_007"><span class="cls_007"></Ellipse.Triggers></span></div>
<div style="position:absolute;left:52.98px;top:43.50px" class="cls_007"><span class="cls_007"></Ellipse></span></div>
<div style="position:absolute;left:5.00px;top:63.75px" class="cls_004"><span class="cls_004">In this example, we declare an </span><span class="cls_007">Ellipse</span><span class="cls_004"> shape with its </span><span class="cls_007">Fill</span><span class="cls_004"> property set to an instance of</span></div>
<div style="position:absolute;left:5.00px;top:81.75px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">RadialGradientBrush</span><span class="cls_004"> class. The brush has a yellow center and is orange around the</span></div>
<div style="position:absolute;left:5.00px;top:99.75px" class="cls_004"><span class="cls_004">edges. Note that these brushes have a property named </span><span class="cls_007">GradientOrigin</span><span class="cls_004"> that specifies the</span></div>
<div style="position:absolute;left:5.00px;top:117.75px" class="cls_004"><span class="cls_004">center point of the gradient and defaults to the point </span><span class="cls_007">0.5</span><span class="cls_004">, </span><span class="cls_007">0.5</span><span class="cls_004">. In this example, we animate</span></div>
<div style="position:absolute;left:5.00px;top:135.75px" class="cls_004"><span class="cls_004">this property, which has a similar effect to moving a light source around a 3D ball.</span></div>
<div style="position:absolute;left:5.00px;top:275.25px" class="cls_004"><span class="cls_004">We use an </span><span class="cls_007">EventTrigger</span><span class="cls_004"> with the </span><span class="cls_007">Loaded</span><span class="cls_004"> event to start our animation and set the</span></div>
<div style="position:absolute;left:5.00px;top:293.25px" class="cls_007"><span class="cls_007">RepeatBehavior</span><span class="cls_004"> property to </span><span class="cls_007">Forever</span><span class="cls_004"> on the associated storyboard. As mentioned, we set</span></div>
<div style="position:absolute;left:5.00px;top:311.25px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">TargetProperty</span><span class="cls_004"> property to the </span><span class="cls_007">GradientOrigin</span><span class="cls_004"> property of the brush that is set as the</span></div>
<div style="position:absolute;left:5.00px;top:329.25px" class="cls_007"><span class="cls_007">Fill</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:5.00px;top:347.25px" class="cls_004"><span class="cls_004">Inside the storyboard, we declare a </span><span class="cls_007">PointAnimationUsingKeyFrames</span><span class="cls_004"> element and directly</span></div>
<div style="position:absolute;left:5.00px;top:365.25px" class="cls_004"><span class="cls_004">inside it, we declare a number of various </span><span class="cls_007"><InterpolationMethod><Type>KeyFrame</span><span class="cls_004"> objects.</span></div>
<div style="position:absolute;left:5.00px;top:383.25px" class="cls_004"><span class="cls_004">As mentioned, we do not need to explicitly declare the </span><span class="cls_007">KeyFrames</span><span class="cls_004"> property in order to</span></div>
<div style="position:absolute;left:5.00px;top:401.25px" class="cls_004"><span class="cls_004">declare these key-frame elements within it.</span></div>
<div style="position:absolute;left:5.00px;top:419.25px" class="cls_004"><span class="cls_004">Note that the </span><span class="cls_007">DiscretePointKeyFrame</span><span class="cls_004"> element that is used here is entirely optional and</span></div>
<div style="position:absolute;left:5.00px;top:437.25px" class="cls_004"><span class="cls_004">would not change anything if removed. This is because the point </span><span class="cls_007">0.5</span><span class="cls_004">, </span><span class="cls_007">0.5</span><span class="cls_004"> is both the</span></div>
<div style="position:absolute;left:5.00px;top:455.25px" class="cls_004"><span class="cls_004">starting value of the animation and default value of the gradient brush and also the ending</span></div>
<div style="position:absolute;left:5.00px;top:473.25px" class="cls_004"><span class="cls_004">value of the animation. Furthermore, if we omit a zero time key-frame, one will be implicitly</span></div>
<div style="position:absolute;left:5.00px;top:491.25px" class="cls_004"><span class="cls_004">added for us with this value.</span></div>
<div style="position:absolute;left:5.00px;top:509.25px" class="cls_004"><span class="cls_004">Next, we declare a </span><span class="cls_007">LinearPointKeyFrame</span><span class="cls_004"> element, that will animate the gradient origin from</span></div>
<div style="position:absolute;left:5.00px;top:527.25px" class="cls_004"><span class="cls_004">the point </span><span class="cls_007">0.5</span><span class="cls_004">, </span><span class="cls_007">0.5</span><span class="cls_004"> to the point </span><span class="cls_007">1.0</span><span class="cls_004">, </span><span class="cls_007">1.0</span><span class="cls_004"> in a linear, even fashion. Following that, we have a</span></div>
<div style="position:absolute;left:5.00px;top:545.25px" class="cls_007"><span class="cls_007">SplinePointKeyFrame</span><span class="cls_004"> element that will animate the gradient origin from the previous point</span></div>
<div style="position:absolute;left:5.00px;top:563.25px" class="cls_004"><span class="cls_004">to the point </span><span class="cls_007">1.0</span><span class="cls_004">, </span><span class="cls_007">0.0</span><span class="cls_004">. Note the </span><span class="cls_007">KeySpline</span><span class="cls_004"> property that adjusts the speed of the animation</span></div>
<div style="position:absolute;left:5.00px;top:581.25px" class="cls_004"><span class="cls_004">as it progresses.</span></div>
<div style="position:absolute;left:5.00px;top:599.25px" class="cls_004"><span class="cls_004">From there, we use another </span><span class="cls_007">LinearPointKeyFrame</span><span class="cls_004"> element to smoothly and evenly</span></div>
<div style="position:absolute;left:5.00px;top:617.25px" class="cls_004"><span class="cls_004">transition to the point </span><span class="cls_007">0.0</span><span class="cls_004">, </span><span class="cls_007">0.0</span><span class="cls_004"> over one second. Finally, we use a second</span></div>
<div style="position:absolute;left:5.00px;top:635.25px" class="cls_007"><span class="cls_007">SplinePointKeyFrame</span><span class="cls_004"> element to animate the gradient origin back to the center of the circle</span></div>
<div style="position:absolute;left:5.00px;top:653.25px" class="cls_004"><span class="cls_004">and its starting position, taking the last three seconds of the total duration.</span></div>
<div style="position:absolute;left:5.00px;top:671.25px" class="cls_004"><span class="cls_004">When this example is run, we can clearly see it animating the gradient origin point evenly</span></div>
<div style="position:absolute;left:5.00px;top:689.25px" class="cls_004"><span class="cls_004">during the periods of the two </span><span class="cls_007">LinearPointKeyFrame</span><span class="cls_004"> elements and change speed during the</span></div>
<div style="position:absolute;left:5.00px;top:707.25px" class="cls_004"><span class="cls_004">periods of the two </span><span class="cls_007">SplinePointKeyFrame</span><span class="cls_004"> elements.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:191678px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background241.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_008"><span class="cls_008">Telling stories</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">While the various animation classes that extend the </span><span class="cls_007">Timeline</span><span class="cls_004"> class can be used to animate</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">control properties directly in code, in order to declare and trigger animations using XAML</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">alone, we need to use the </span><span class="cls_007">Storyboard</span><span class="cls_004"> class. This is what is known as a container timeline,</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">as it extends the abstract </span><span class="cls_007">TimelineGroup</span><span class="cls_004"> class that enables it to contain child timelines.</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">Another container timeline class that the </span><span class="cls_007">Storyboard</span><span class="cls_004"> class extends is the </span><span class="cls_007">ParallelTimeline</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">class and these classes enable us to group child timelines and to set properties on them as</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">a group. When creating more complex animations, if all we need to do is to delay the start</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">of a group of child timelines, we should use the </span><span class="cls_007">ParallelTimeline</span><span class="cls_004"> class rather than the</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_007"><span class="cls_007">Storyboard</span><span class="cls_004"> class, as it is more efficient.</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">We could rewrite our earlier </span><span class="cls_007">BeginTime</span><span class="cls_004"> example to use a </span><span class="cls_007">ParallelTimeline</span><span class="cls_004"> element to</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">delay the start of our last two timelines. Let's see what that might look like.</span></div>
<div style="position:absolute;left:52.98px;top:243.00px" class="cls_007"><span class="cls_007"><Storyboard></span></div>
<div style="position:absolute;left:67.97px;top:256.50px" class="cls_007"><span class="cls_007"><DoubleAnimation Storyboard.TargetProperty="Width" To="300.0"</span></div>
<div style="position:absolute;left:82.97px;top:270.00px" class="cls_007"><span class="cls_007">Duration="0:0:2" /></span></div>
<div style="position:absolute;left:67.97px;top:283.50px" class="cls_007"><span class="cls_007"><DoubleAnimation Storyboard.TargetProperty="Height" To="300.0"</span></div>
<div style="position:absolute;left:82.97px;top:297.00px" class="cls_007"><span class="cls_007">Duration="0:0:2" BeginTime="0:0:2" /></span></div>
<div style="position:absolute;left:67.97px;top:310.50px" class="cls_007"><span class="cls_007"><ParallelTimeline BeginTime="0:0:4"></span></div>
<div style="position:absolute;left:82.97px;top:324.00px" class="cls_007"><span class="cls_007"><DoubleAnimation Storyboard.TargetProperty="Width" To="0.0"</span></div>
<div style="position:absolute;left:97.96px;top:337.50px" class="cls_007"><span class="cls_007">Duration="0:0:2" /></span></div>
<div style="position:absolute;left:82.97px;top:351.00px" class="cls_007"><span class="cls_007"><DoubleAnimation Storyboard.TargetProperty="Height" To="0.0"</span></div>
<div style="position:absolute;left:97.96px;top:364.50px" class="cls_007"><span class="cls_007">Duration="0:0:2" /></span></div>
<div style="position:absolute;left:67.97px;top:378.00px" class="cls_007"><span class="cls_007"></ParallelTimeline></span></div>
<div style="position:absolute;left:52.98px;top:391.50px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:5.00px;top:411.75px" class="cls_004"><span class="cls_004">As the </span><span class="cls_007">Storyboard</span><span class="cls_004"> class is a </span><span class="cls_007">Timeline</span><span class="cls_004"> object, it also has the same properties as the</span></div>
<div style="position:absolute;left:5.00px;top:429.75px" class="cls_004"><span class="cls_004">various animation objects. One additional property that it inherits from the</span></div>
<div style="position:absolute;left:5.00px;top:447.75px" class="cls_007"><span class="cls_007">ParallelTimeline</span><span class="cls_004"> class is the </span><span class="cls_007">SlipBehavior</span><span class="cls_004"> property. This property is only really useful</span></div>
<div style="position:absolute;left:5.00px;top:465.75px" class="cls_004"><span class="cls_004">when we want to synchronize an animation timeline with the playback of a </span><span class="cls_007">MediaTimeline</span></div>
<div style="position:absolute;left:5.00px;top:483.75px" class="cls_004"><span class="cls_004">element, but it's worth knowing about.</span></div>
<div style="position:absolute;left:5.00px;top:501.75px" class="cls_004"><span class="cls_004">This property is of the enumeration type </span><span class="cls_007">SlipBehavior</span><span class="cls_004"> and it only has two members. A</span></div>
<div style="position:absolute;left:5.00px;top:519.75px" class="cls_004"><span class="cls_004">value of </span><span class="cls_007">Grow</span><span class="cls_004"> specifies that we do not need our animation timelines to be synchronized with</span></div>
<div style="position:absolute;left:5.00px;top:537.75px" class="cls_004"><span class="cls_004">our media timeline(s) and is the default value of this property.</span></div>
<div style="position:absolute;left:5.00px;top:555.75px" class="cls_004"><span class="cls_004">Conversely, a value of </span><span class="cls_007">Slip</span><span class="cls_004"> indicates that we want our animation timelines to slip, either</span></div>
<div style="position:absolute;left:5.00px;top:573.75px" class="cls_004"><span class="cls_004">forwards or backwards, whenever necessary in order to keep them in sync with the playing</span></div>
<div style="position:absolute;left:5.00px;top:591.75px" class="cls_004"><span class="cls_004">media. If the media takes time to load when using this setting, then the animation timelines</span></div>
<div style="position:absolute;left:5.00px;top:609.75px" class="cls_004"><span class="cls_004">within the storyboard will wait until the media is ready and continue at that point.</span></div>
<div style="position:absolute;left:5.00px;top:627.75px" class="cls_004"><span class="cls_004">In addition to the properties that have been inherited from the various base classes, the</span></div>
<div style="position:absolute;left:5.00px;top:645.75px" class="cls_007"><span class="cls_007">Storyboard</span><span class="cls_004"> class also declares three important Attached Properties that are essential for</span></div>
<div style="position:absolute;left:5.00px;top:663.75px" class="cls_004"><span class="cls_004">targeting animations to individual UI elements and/or their properties.</span></div>
<div style="position:absolute;left:5.00px;top:681.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">Storyboard.Target</span><span class="cls_004"> Attached Property specifies the UI control that should be animated,</span></div>
<div style="position:absolute;left:5.00px;top:699.75px" class="cls_004"><span class="cls_004">although setting this property alone is not enough, as it does not specify the target property.</span></div>
<div style="position:absolute;left:5.00px;top:717.75px" class="cls_004"><span class="cls_004">This property is of type </span><span class="cls_007">object</span><span class="cls_004">, although it can only be used with objects of type</span></div>
<div style="position:absolute;left:5.00px;top:735.75px" class="cls_007"><span class="cls_007">DependencyObject</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:753.75px" class="cls_004"><span class="cls_004">In order to use this property, we need to specify a binding path that references the target</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:192480px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background242.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">UI control. If the target element extends the </span><span class="cls_007">FrameworkElement</span><span class="cls_004"> or</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_007"><span class="cls_007">FrameworkContentElement</span><span class="cls_004"> classes, then one way would be to name the target element and</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">to use an </span><span class="cls_007">ElementName</span><span class="cls_004"> binding to reference it.</span></div>
<div style="position:absolute;left:52.98px;top:63.00px" class="cls_007"><span class="cls_007">Storyboard.Target="{Binding ElementName=TargetControlName}"</span></div>
<div style="position:absolute;left:5.00px;top:83.25px" class="cls_004"><span class="cls_004">Most UI elements extend one of these two classes that declare the </span><span class="cls_007">Name</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:5.00px;top:101.25px" class="cls_004"><span class="cls_004">However, if we provide a name for the target control, then there is a simpler way to target</span></div>
<div style="position:absolute;left:5.00px;top:119.25px" class="cls_004"><span class="cls_004">it. Instead of using the </span><span class="cls_007">Storyboard.Target</span><span class="cls_004"> property, we could use the</span></div>
<div style="position:absolute;left:5.00px;top:137.25px" class="cls_007"><span class="cls_007">Storyboard.TargetName</span><span class="cls_004"> Attached Property to specify the target element using just their</span></div>
<div style="position:absolute;left:5.00px;top:155.25px" class="cls_004"><span class="cls_004">declared name, without any binding.</span></div>
<div style="position:absolute;left:52.98px;top:178.50px" class="cls_007"><span class="cls_007">Storyboard.TargetName="TargetControlName"</span></div>
<div style="position:absolute;left:5.00px;top:198.75px" class="cls_004"><span class="cls_004">We do not always need to specify this property value, as on occasion, the target element</span></div>
<div style="position:absolute;left:5.00px;top:216.75px" class="cls_004"><span class="cls_004">can be worked out implicitly. If the relevant storyboard was started with a </span><span class="cls_007">BeginStoryboard</span></div>
<div style="position:absolute;left:5.00px;top:234.75px" class="cls_004"><span class="cls_004">element, the UI element that declared it will be targeted. Additionally, if the relevant</span></div>
<div style="position:absolute;left:5.00px;top:252.75px" class="cls_004"><span class="cls_004">storyboard is a child of another timeline, then the target of the parent timeline will be</span></div>
<div style="position:absolute;left:5.00px;top:270.75px" class="cls_004"><span class="cls_004">inherited.</span></div>
<div style="position:absolute;left:5.00px;top:288.75px" class="cls_004"><span class="cls_004">The most important property that the </span><span class="cls_007">Storyboard</span><span class="cls_004"> class declares is the </span><span class="cls_007">TargetProperty</span></div>
<div style="position:absolute;left:5.00px;top:306.75px" class="cls_004"><span class="cls_004">Attached Property. We use this property to specify which property on the target element</span></div>
<div style="position:absolute;left:5.00px;top:324.75px" class="cls_004"><span class="cls_004">that we want to animate. Note that in order for this to work, the target property must be a</span></div>
<div style="position:absolute;left:5.00px;top:342.75px" class="cls_004"><span class="cls_004">Dependency Property.</span></div>
<div style="position:absolute;left:5.00px;top:360.75px" class="cls_004"><span class="cls_004">Occasionally, we may want to target objects that do not extend either of the framework</span></div>
<div style="position:absolute;left:5.00px;top:378.75px" class="cls_004"><span class="cls_004">classes mentioned earlier; in WPF, we are also able to target freezable classes that extend</span></div>
<div style="position:absolute;left:5.00px;top:396.75px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">Freezable</span><span class="cls_004"> class. In order to target one of these classes in XAML, we need to specify</span></div>
<div style="position:absolute;left:5.00px;top:414.75px" class="cls_004"><span class="cls_004">the name of the object using the </span><span class="cls_007">x:Name</span><span class="cls_004"> directive instead, as they have no </span><span class="cls_007">Name</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:5.00px;top:432.75px" class="cls_004"><span class="cls_004">As a side note, WPF classes that declare their own </span><span class="cls_007">Name</span><span class="cls_004"> property actually map the name</span></div>
<div style="position:absolute;left:5.00px;top:450.75px" class="cls_004"><span class="cls_004">value through to the </span><span class="cls_007">x:Name</span><span class="cls_004"> directive, which is part of the XAML specification. In these</span></div>
<div style="position:absolute;left:5.00px;top:468.75px" class="cls_004"><span class="cls_004">cases, we are free to use either of these to register a name for an element, but we must</span></div>
<div style="position:absolute;left:5.00px;top:486.75px" class="cls_004"><span class="cls_004">not set both. Note that unnamed elements can still be referenced by our animations,</span></div>
<div style="position:absolute;left:5.00px;top:504.75px" class="cls_004"><span class="cls_004">although they need to be indirectly referenced. Instead of referencing them directly, we</span></div>
<div style="position:absolute;left:5.00px;top:522.75px" class="cls_004"><span class="cls_004">need to specify the name of the parent property or freezable object and then chain</span></div>
<div style="position:absolute;left:5.00px;top:540.75px" class="cls_004"><span class="cls_004">properties in the </span><span class="cls_007">TargetProperty</span><span class="cls_004"> Attached Property, until we reach the desired element.</span></div>
<div style="position:absolute;left:5.00px;top:558.75px" class="cls_004"><span class="cls_004">We used this method in the last example of the previous section.</span></div>
<div style="position:absolute;left:52.98px;top:582.00px" class="cls_007"><span class="cls_007">Storyboard.TargetProperty="Fill.GradientOrigin"</span></div>
<div style="position:absolute;left:5.00px;top:602.25px" class="cls_004"><span class="cls_004">In this case, we reference the </span><span class="cls_007">Fill</span><span class="cls_004"> property, which is of type </span><span class="cls_007">RadialGradientBrush</span><span class="cls_004"> and</span></div>
<div style="position:absolute;left:5.00px;top:620.25px" class="cls_004"><span class="cls_004">then we chain to the </span><span class="cls_007">GradientOrigin</span><span class="cls_004"> property of the brush from there. Note that if we had</span></div>
<div style="position:absolute;left:5.00px;top:638.25px" class="cls_004"><span class="cls_004">used an instance of the </span><span class="cls_007">SolidColorBrush</span><span class="cls_004"> class here instead, this reference would fail,</span></div>
<div style="position:absolute;left:5.00px;top:656.25px" class="cls_004"><span class="cls_004">because there is no </span><span class="cls_007">GradientOrigin</span><span class="cls_004"> property in that brush. However, while the animation</span></div>
<div style="position:absolute;left:5.00px;top:674.25px" class="cls_004"><span class="cls_004">would fail to work, this would not cause any errors to be raised.</span></div>
<div style="position:absolute;left:5.00px;top:691.51px" class="cls_011"><span class="cls_011">Controlling storyboards</span></div>
<div style="position:absolute;left:5.00px;top:721.50px" class="cls_004"><span class="cls_004">In order to start a storyboard in XAML, we need to use a </span><span class="cls_007">BeginStoryboard</span><span class="cls_004"> element. This</span></div>
<div style="position:absolute;left:5.00px;top:739.50px" class="cls_004"><span class="cls_004">class extends the </span><span class="cls_007">TriggerAction</span><span class="cls_004"> class and if you remember, that is the type that we need</span></div>
<div style="position:absolute;left:5.00px;top:757.50px" class="cls_004"><span class="cls_004">to use in the </span><span class="cls_007">TriggerActionCollection</span><span class="cls_004"> of the </span><span class="cls_007">EventTrigger</span><span class="cls_004"> class and the</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:193282px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background243.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_007"><span class="cls_007">TriggerBase</span><span class="cls_004">.</span><span class="cls_007">EnterActions</span><span class="cls_004"> and </span><span class="cls_007">TriggerBase</span><span class="cls_004">.</span><span class="cls_007">ExitActions</span><span class="cls_004"> properties.</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">We specify the storyboard to use with the </span><span class="cls_007">BeginStoryboard</span><span class="cls_004"> element by setting it to the</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_007"><span class="cls_007">Storyboard</span><span class="cls_004"> property in code. When using XAML, the </span><span class="cls_007">Storyboard</span><span class="cls_004"> property is implicitly set to</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">the storyboard that is declared within the </span><span class="cls_007">BeginStoryboard</span><span class="cls_004"> element.</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">BeginStoryboard</span><span class="cls_004"> action is responsible for connecting the animation timelines with the</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">animation targets and their targeted properties and is also responsible for starting the</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">various animation timelines within its storyboard. It does this by calling the </span><span class="cls_007">Begin</span><span class="cls_004"> method of</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">the associated </span><span class="cls_007">Storyboard</span><span class="cls_004"> object, once its parent's trigger condition has been met.</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">If an already running storyboard is asked to begin again, either indirectly, using a</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_007"><span class="cls_007">BeginStoryboard</span><span class="cls_004"> action, or directly, using the </span><span class="cls_007">Begin</span><span class="cls_004"> method, what happens will depend</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">upon the value set by the </span><span class="cls_007">HandoffBehavior</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">This property is of the enumeration type </span><span class="cls_007">HandoffBehavior</span><span class="cls_004"> and has two values. The default</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">value is </span><span class="cls_007">SnapshotAndReplace</span><span class="cls_004"> and this will renew the internal clocks and essentially have the</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">effect of replacing one copy of the timeline with another. The other value is more</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">interesting; the </span><span class="cls_007">Compose</span><span class="cls_004"> value will retain the original clocks when restarting the animation</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">and append the new animation after the current one, performing some interpolation</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">between them, resulting in a smoother join.</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">One problem with this method is that the retained clocks will continue to use system</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_004"><span class="cls_004">resources and this can end in memory problems if not handled correctly. However, this</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_004"><span class="cls_004">method produces much smoother and more natural and fluid animations that can be worth</span></div>
<div style="position:absolute;left:5.00px;top:363.75px" class="cls_004"><span class="cls_004">the extra resources. This is best demonstrated with a small example.</span></div>
<div style="position:absolute;left:52.98px;top:387.00px" class="cls_007"><span class="cls_007"><Canvas></span></div>
<div style="position:absolute;left:67.97px;top:400.50px" class="cls_007"><span class="cls_007"><Rectangle Canvas.Top="200" Canvas.Left="25" Width="100"</span></div>
<div style="position:absolute;left:52.98px;top:414.00px" class="cls_007"><span class="cls_007">Height="100"</span></div>
<div style="position:absolute;left:82.97px;top:427.50px" class="cls_007"><span class="cls_007">Fill="Orange" Stroke="Black" StrokeThickness="3"></span></div>
<div style="position:absolute;left:82.97px;top:441.00px" class="cls_007"><span class="cls_007"><Rectangle.Style></span></div>
<div style="position:absolute;left:97.96px;top:454.50px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type Rectangle}"></span></div>
<div style="position:absolute;left:112.96px;top:468.00px" class="cls_007"><span class="cls_007"><Style.Triggers></span></div>
<div style="position:absolute;left:127.95px;top:481.50px" class="cls_007"><span class="cls_007"><Trigger Property="IsMouseOver" Value="True"></span></div>
<div style="position:absolute;left:142.94px;top:495.00px" class="cls_007"><span class="cls_007"><Trigger.EnterActions></span></div>
<div style="position:absolute;left:157.94px;top:508.50px" class="cls_007"><span class="cls_007"><BeginStoryboard></span></div>
<div style="position:absolute;left:172.93px;top:522.00px" class="cls_007"><span class="cls_007"><Storyboard></span></div>
<div style="position:absolute;left:187.92px;top:535.50px" class="cls_007"><span class="cls_007"><DoubleAnimation Duration="0:0:2"</span></div>
<div style="position:absolute;left:202.92px;top:549.00px" class="cls_007"><span class="cls_007">Storyboard.TargetProperty="(Canvas.Top)" To="0"</span></div>
<div style="position:absolute;left:52.98px;top:562.50px" class="cls_007"><span class="cls_007">/></span></div>
<div style="position:absolute;left:172.93px;top:576.00px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:157.94px;top:589.50px" class="cls_007"><span class="cls_007"></BeginStoryboard></span></div>
<div style="position:absolute;left:142.94px;top:603.00px" class="cls_007"><span class="cls_007"></Trigger.EnterActions></span></div>
<div style="position:absolute;left:142.94px;top:616.50px" class="cls_007"><span class="cls_007"><Trigger.ExitActions></span></div>
<div style="position:absolute;left:157.94px;top:630.00px" class="cls_007"><span class="cls_007"><BeginStoryboard></span></div>
<div style="position:absolute;left:172.93px;top:643.50px" class="cls_007"><span class="cls_007"><Storyboard></span></div>
<div style="position:absolute;left:187.92px;top:657.00px" class="cls_007"><span class="cls_007"><DoubleAnimation Duration="0:0:2"</span></div>
<div style="position:absolute;left:202.92px;top:670.50px" class="cls_007"><span class="cls_007">Storyboard.TargetProperty="(Canvas.Top)"</span></div>
<div style="position:absolute;left:52.98px;top:684.00px" class="cls_007"><span class="cls_007">To="200" /></span></div>
<div style="position:absolute;left:172.93px;top:697.50px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:157.94px;top:711.00px" class="cls_007"><span class="cls_007"></BeginStoryboard></span></div>
<div style="position:absolute;left:142.94px;top:724.50px" class="cls_007"><span class="cls_007"></Trigger.ExitActions></span></div>
<div style="position:absolute;left:127.95px;top:738.00px" class="cls_007"><span class="cls_007"></Trigger></span></div>
<div style="position:absolute;left:112.96px;top:751.50px" class="cls_007"><span class="cls_007"></Style.Triggers></span></div>
<div style="position:absolute;left:97.96px;top:765.00px" class="cls_007"><span class="cls_007"></Style></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:194084px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background244.jpg" width=612 height=792></div>
<div style="position:absolute;left:82.97px;top:3.00px" class="cls_007"><span class="cls_007"></Rectangle.Style></span></div>
<div style="position:absolute;left:67.97px;top:16.50px" class="cls_007"><span class="cls_007"></Rectangle></span></div>
<div style="position:absolute;left:67.97px;top:30.00px" class="cls_007"><span class="cls_007"><Rectangle Canvas.Top="200" Canvas.Left="150" Width="100"</span></div>
<div style="position:absolute;left:52.98px;top:43.50px" class="cls_007"><span class="cls_007">Height="100"</span></div>
<div style="position:absolute;left:82.97px;top:57.00px" class="cls_007"><span class="cls_007">Fill="Orange" Stroke="Black" StrokeThickness="3"></span></div>
<div style="position:absolute;left:82.97px;top:70.50px" class="cls_007"><span class="cls_007"><Rectangle.Style></span></div>
<div style="position:absolute;left:97.96px;top:84.00px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type Rectangle}"></span></div>
<div style="position:absolute;left:112.96px;top:97.50px" class="cls_007"><span class="cls_007"><Style.Triggers></span></div>
<div style="position:absolute;left:127.95px;top:111.00px" class="cls_007"><span class="cls_007"><Trigger Property="IsMouseOver" Value="True"></span></div>
<div style="position:absolute;left:142.94px;top:124.50px" class="cls_007"><span class="cls_007"><Trigger.EnterActions></span></div>
<div style="position:absolute;left:157.94px;top:138.00px" class="cls_007"><span class="cls_007"><BeginStoryboard></span></div>
<div style="position:absolute;left:172.93px;top:151.50px" class="cls_007"><span class="cls_007"><Storyboard></span></div>
<div style="position:absolute;left:187.92px;top:165.00px" class="cls_007"><span class="cls_007"><DoubleAnimation Duration="0:0:2"</span></div>
<div style="position:absolute;left:202.92px;top:178.50px" class="cls_007"><span class="cls_007">Storyboard.TargetProperty="(Canvas.Top)" To="0"</span></div>
<div style="position:absolute;left:52.98px;top:192.00px" class="cls_007"><span class="cls_007">/></span></div>
<div style="position:absolute;left:172.93px;top:205.50px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:157.94px;top:219.00px" class="cls_007"><span class="cls_007"></BeginStoryboard></span></div>
<div style="position:absolute;left:142.94px;top:232.50px" class="cls_007"><span class="cls_007"></Trigger.EnterActions></span></div>
<div style="position:absolute;left:142.94px;top:246.00px" class="cls_007"><span class="cls_007"><Trigger.ExitActions></span></div>
<div style="position:absolute;left:157.94px;top:259.50px" class="cls_007"><span class="cls_007"><BeginStoryboard HandoffBehavior="Compose"></span></div>
<div style="position:absolute;left:172.93px;top:273.00px" class="cls_007"><span class="cls_007"><Storyboard></span></div>
<div style="position:absolute;left:187.92px;top:286.50px" class="cls_007"><span class="cls_007"><DoubleAnimation Duration="0:0:2"</span></div>
<div style="position:absolute;left:202.92px;top:300.00px" class="cls_007"><span class="cls_007">Storyboard.TargetProperty="(Canvas.Top)"</span></div>
<div style="position:absolute;left:52.98px;top:313.50px" class="cls_007"><span class="cls_007">To="200" /></span></div>
<div style="position:absolute;left:172.93px;top:327.00px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:157.94px;top:340.50px" class="cls_007"><span class="cls_007"></BeginStoryboard></span></div>
<div style="position:absolute;left:142.94px;top:354.00px" class="cls_007"><span class="cls_007"></Trigger.ExitActions></span></div>
<div style="position:absolute;left:127.95px;top:367.50px" class="cls_007"><span class="cls_007"></Trigger></span></div>
<div style="position:absolute;left:112.96px;top:381.00px" class="cls_007"><span class="cls_007"></Style.Triggers></span></div>
<div style="position:absolute;left:97.96px;top:394.50px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:82.97px;top:408.00px" class="cls_007"><span class="cls_007"></Rectangle.Style></span></div>
<div style="position:absolute;left:67.97px;top:421.50px" class="cls_007"><span class="cls_007"></Rectangle></span></div>
<div style="position:absolute;left:52.98px;top:435.00px" class="cls_007"><span class="cls_007"></Canvas></span></div>
<div style="position:absolute;left:5.00px;top:455.25px" class="cls_004"><span class="cls_004">In this example, we have two rectangles, each with its own animation. The only difference</span></div>
<div style="position:absolute;left:5.00px;top:473.25px" class="cls_004"><span class="cls_004">between them is that the </span><span class="cls_007">BeginStoryboard</span><span class="cls_004"> element that starts the animation for the right</span></div>
<div style="position:absolute;left:5.00px;top:491.25px" class="cls_004"><span class="cls_004">rectangle has a </span><span class="cls_007">HandoffBehavior</span><span class="cls_004"> of </span><span class="cls_007">Compose</span><span class="cls_004">, while the other uses the default value of</span></div>
<div style="position:absolute;left:5.00px;top:509.25px" class="cls_007"><span class="cls_007">SnapshotAndReplace</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:527.25px" class="cls_004"><span class="cls_004">When the example is run, each rectangle will move upwards when the mouse cursor is</span></div>
<div style="position:absolute;left:5.00px;top:545.25px" class="cls_004"><span class="cls_004">placed over it and move back downwards when the cursor is moved away from it. If we</span></div>
<div style="position:absolute;left:5.00px;top:563.25px" class="cls_004"><span class="cls_004">keep the mouse cursor within the bounds of each rectangle, moving it up to the top of the</span></div>
<div style="position:absolute;left:5.00px;top:581.25px" class="cls_004"><span class="cls_004">screen with the rectangle and then move the cursor away to let the rectangle fall, the two</span></div>
<div style="position:absolute;left:5.00px;top:599.25px" class="cls_004"><span class="cls_004">animations will appear identical.</span></div>
<div style="position:absolute;left:5.00px;top:617.25px" class="cls_004"><span class="cls_004">However, if we move the mouse cursor from side to side across the two rectangles, we will</span></div>
<div style="position:absolute;left:5.00px;top:635.25px" class="cls_004"><span class="cls_004">start to see a difference between the two animations. We'll see that as the cursor enters</span></div>
<div style="position:absolute;left:5.00px;top:653.25px" class="cls_004"><span class="cls_004">the bounds of each rectangle, they each start their upward movement. But once the cursor</span></div>
<div style="position:absolute;left:5.00px;top:671.25px" class="cls_004"><span class="cls_004">leaves the rectangle bounds, we see the difference.</span></div>
<div style="position:absolute;left:5.00px;top:689.25px" class="cls_004"><span class="cls_004">The rectangle on the left with the default value of </span><span class="cls_007">SnapshotAndReplace</span><span class="cls_004">, will stop moving up</span></div>
<div style="position:absolute;left:5.00px;top:707.25px" class="cls_004"><span class="cls_004">and immediately begin its downward animation, while the other rectangle will continue to</span></div>
<div style="position:absolute;left:5.00px;top:725.25px" class="cls_004"><span class="cls_004">move upward for a short time before commencing its downward animation. This results in a</span></div>
<div style="position:absolute;left:5.00px;top:743.25px" class="cls_004"><span class="cls_004">much smoother, more natural looking transition between the two animations.</span></div>
<div style="position:absolute;left:5.00px;top:761.25px" class="cls_004"><span class="cls_004">The difference between these two handoff behaviors though, is most clearly demonstrated</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:194886px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background245.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">by simply placing the mouse cursor on one of the rectangles and leaving it there. Doing this</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">to the rectangle on the left will cause the rectangle to move upward until the mouse cursor</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">is no longer within its bounds and then it will immediately begin to move downwards again.</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">However, as the mouse cursor will then be within the bounds of the rectangle again, it will</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">begin the upwards animation once more. This will cause the rectangle to move away from</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">the mouse cursor again and so we will end with a repetitive loop of this behavior and it will</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">result in what looks like a quick shaking, or stuttering, of the rectangle just above the</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">position of the mouse.</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">On the other hand, the rectangle on the right, with the </span><span class="cls_007">HandoffBehavior</span><span class="cls_004"> of </span><span class="cls_007">Compose</span><span class="cls_004"> will</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">move upward until the mouse cursor is no longer within its bounds, but will then continue to</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">move upwards for a short time before starting to move downwards again. Once more, this</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">creates a far smoother animation and will result in the rectangle bouncing gently above the</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">mouse cursor, in sharp contrast to the other, stuttering rectangle.</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">There are several related </span><span class="cls_007">TriggerAction</span><span class="cls_004"> derived classes that are suffixed with the word</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_007"><span class="cls_007">Storyboard</span><span class="cls_004"> and enable us to control various aspects of the related </span><span class="cls_007">Storyboard</span><span class="cls_004"> element. By</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">specifying the </span><span class="cls_007">Name</span><span class="cls_004"> property value of the </span><span class="cls_007">BeginStoryboard</span><span class="cls_004"> element in the</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_007"><span class="cls_007">BeginStoryboardName</span><span class="cls_004"> property of the other actions, we are able to further control the</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">running storyboard.</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_004"><span class="cls_004">We can use the </span><span class="cls_007">PauseStoryboard</span><span class="cls_004"> element to pause a running storyboard and the</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_007"><span class="cls_007">ResumeStoryboard</span><span class="cls_004"> to resume a paused storyboard. The </span><span class="cls_007">PauseStoryboard</span><span class="cls_004"> element does</span></div>
<div style="position:absolute;left:5.00px;top:363.75px" class="cls_004"><span class="cls_004">nothing if the related storyboard is not running and similarly, the </span><span class="cls_007">ResumeStoryboard</span><span class="cls_004"> action</span></div>
<div style="position:absolute;left:5.00px;top:381.75px" class="cls_004"><span class="cls_004">does nothing if the related storyboard is not already paused. Therefore, a storyboard</span></div>
<div style="position:absolute;left:5.00px;top:399.75px" class="cls_004"><span class="cls_004">cannot be started with a </span><span class="cls_007">ResumeStoryboard</span><span class="cls_004"> trigger action.</span></div>
<div style="position:absolute;left:5.00px;top:417.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">StopStoryboard</span><span class="cls_004"> action will stop a running storyboard, but does nothing if the related</span></div>
<div style="position:absolute;left:5.00px;top:435.75px" class="cls_004"><span class="cls_004">storyboard is not already running. Finally, there is a </span><span class="cls_007">RemoveStoryboard</span><span class="cls_004"> trigger action that</span></div>
<div style="position:absolute;left:5.00px;top:453.75px" class="cls_004"><span class="cls_004">will remove a storyboard when its parent's trigger condition has been met. As storyboards</span></div>
<div style="position:absolute;left:5.00px;top:471.75px" class="cls_004"><span class="cls_004">consume resources, we should remove them when they are no longer required.</span></div>
<div style="position:absolute;left:5.00px;top:489.75px" class="cls_004"><span class="cls_004">For example, if we use an </span><span class="cls_007">EventTrigger</span><span class="cls_004"> with the </span><span class="cls_007">Loaded</span><span class="cls_004"> event to start a timeline that has</span></div>
<div style="position:absolute;left:5.00px;top:507.75px" class="cls_004"><span class="cls_004">its </span><span class="cls_007">RepeatBehavior</span><span class="cls_004"> property set to </span><span class="cls_007">Forever</span><span class="cls_004">, then we should use another </span><span class="cls_007">EventTrigger</span></div>
<div style="position:absolute;left:5.00px;top:525.75px" class="cls_004"><span class="cls_004">element with a </span><span class="cls_007">RemoveStoryboard</span><span class="cls_004"> action in the </span><span class="cls_007">Unloaded</span><span class="cls_004"> event to remove the storyboard.</span></div>
<div style="position:absolute;left:5.00px;top:543.75px" class="cls_004"><span class="cls_004">This is somewhat analogous to calling the </span><span class="cls_007">Dispose</span><span class="cls_004"> method on an </span><span class="cls_007">IDisposable</span></div>
<div style="position:absolute;left:5.00px;top:561.75px" class="cls_004"><span class="cls_004">implementation.</span></div>
<div style="position:absolute;left:5.00px;top:579.75px" class="cls_004"><span class="cls_004">Note that it is essential to remove a storyboard that was started by a </span><span class="cls_007">BeginStoryboard</span></div>
<div style="position:absolute;left:5.00px;top:597.75px" class="cls_004"><span class="cls_004">action with its </span><span class="cls_007">HandoffBehavior</span><span class="cls_004"> property set to </span><span class="cls_007">Compose</span><span class="cls_004">, as it could end with many internal</span></div>
<div style="position:absolute;left:5.00px;top:615.75px" class="cls_004"><span class="cls_004">clocks being instantiated, but not disposed of. Removing the storyboard will also result in</span></div>
<div style="position:absolute;left:5.00px;top:633.75px" class="cls_004"><span class="cls_004">the internally used clocks being disposed of. Let's see a practical example of how we might</span></div>
<div style="position:absolute;left:5.00px;top:651.75px" class="cls_004"><span class="cls_004">use these elements.</span></div>
<div style="position:absolute;left:52.98px;top:675.00px" class="cls_007"><span class="cls_007"><StackPanel TextElement.FontSize="14"></span></div>
<div style="position:absolute;left:67.97px;top:688.50px" class="cls_007"><span class="cls_007"><TextBox Text="{Binding Name,</span></div>
<div style="position:absolute;left:52.98px;top:702.00px" class="cls_007"><span class="cls_007">UpdateSourceTrigger=PropertyChanged}"</span></div>
<div style="position:absolute;left:82.97px;top:715.50px" class="cls_007"><span class="cls_007">Margin="20"></span></div>
<div style="position:absolute;left:82.97px;top:729.00px" class="cls_007"><span class="cls_007"><TextBox.Effect></span></div>
<div style="position:absolute;left:97.96px;top:742.50px" class="cls_007"><span class="cls_007"><DropShadowEffect Color="Red" ShadowDepth="0" BlurRadius="0"</span></div>
<div style="position:absolute;left:112.96px;top:756.00px" class="cls_007"><span class="cls_007">Opacity="0.5" /></span></div>
<div style="position:absolute;left:82.97px;top:769.50px" class="cls_007"><span class="cls_007"></TextBox.Effect></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:195688px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background246.jpg" width=612 height=792></div>
<div style="position:absolute;left:82.97px;top:3.00px" class="cls_007"><span class="cls_007"><TextBox.Style></span></div>
<div style="position:absolute;left:97.96px;top:16.50px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type TextBox}"></span></div>
<div style="position:absolute;left:112.96px;top:30.00px" class="cls_007"><span class="cls_007"><Style.Triggers></span></div>
<div style="position:absolute;left:127.95px;top:43.50px" class="cls_007"><span class="cls_007"><DataTrigger Binding="{Binding IsValid}" Value="False"></span></div>
<div style="position:absolute;left:142.94px;top:57.00px" class="cls_007"><span class="cls_007"><DataTrigger.EnterActions></span></div>
<div style="position:absolute;left:157.94px;top:70.50px" class="cls_007"><span class="cls_007"><BeginStoryboard Name="GlowStoryboard"></span></div>
<div style="position:absolute;left:172.93px;top:84.00px" class="cls_007"><span class="cls_007"><Storyboard RepeatBehavior="Forever"></span></div>
<div style="position:absolute;left:187.92px;top:97.50px" class="cls_007"><span class="cls_007"><DoubleAnimation Storyboard.</span></div>
<div style="position:absolute;left:202.92px;top:111.00px" class="cls_007"><span class="cls_007">TargetProperty="Effect.</span></div>
<div style="position:absolute;left:52.98px;top:124.50px" class="cls_007"><span class="cls_007">(DropShadowEffect.BlurRadius)"</span></div>
<div style="position:absolute;left:202.92px;top:138.00px" class="cls_007"><span class="cls_007">To="25" Duration="0:0:1.0" AutoReverse="True"</span></div>
<div style="position:absolute;left:52.98px;top:151.50px" class="cls_007"><span class="cls_007">/></span></div>
<div style="position:absolute;left:172.93px;top:165.00px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:157.94px;top:178.50px" class="cls_007"><span class="cls_007"></BeginStoryboard></span></div>
<div style="position:absolute;left:142.94px;top:192.00px" class="cls_007"><span class="cls_007"></DataTrigger.EnterActions></span></div>
<div style="position:absolute;left:127.95px;top:205.50px" class="cls_007"><span class="cls_007"></DataTrigger></span></div>
<div style="position:absolute;left:127.95px;top:219.00px" class="cls_007"><span class="cls_007"><MultiDataTrigger></span></div>
<div style="position:absolute;left:142.94px;top:232.50px" class="cls_007"><span class="cls_007"><MultiDataTrigger.Conditions></span></div>
<div style="position:absolute;left:157.94px;top:246.00px" class="cls_007"><span class="cls_007"><Condition Binding="{Binding IsValid}" Value="False"</span></div>
<div style="position:absolute;left:52.98px;top:259.50px" class="cls_007"><span class="cls_007">/></span></div>
<div style="position:absolute;left:157.94px;top:273.00px" class="cls_007"><span class="cls_007"><Condition Binding="{Binding IsFocused,</span></div>
<div style="position:absolute;left:172.93px;top:286.50px" class="cls_007"><span class="cls_007">RelativeSource={RelativeSource Self}}" Value="True"</span></div>
<div style="position:absolute;left:52.98px;top:300.00px" class="cls_007"><span class="cls_007">/></span></div>
<div style="position:absolute;left:142.94px;top:313.50px" class="cls_007"><span class="cls_007"></MultiDataTrigger.Conditions></span></div>
<div style="position:absolute;left:142.94px;top:327.00px" class="cls_007"><span class="cls_007"><MultiDataTrigger.EnterActions></span></div>
<div style="position:absolute;left:157.94px;top:340.50px" class="cls_007"><span class="cls_007"><PauseStoryboard BeginStoryboardName="GlowStoryboard"</span></div>
<div style="position:absolute;left:52.98px;top:354.00px" class="cls_007"><span class="cls_007">/></span></div>
<div style="position:absolute;left:142.94px;top:367.50px" class="cls_007"><span class="cls_007"></MultiDataTrigger.EnterActions></span></div>
<div style="position:absolute;left:127.95px;top:381.00px" class="cls_007"><span class="cls_007"></MultiDataTrigger></span></div>
<div style="position:absolute;left:127.95px;top:394.50px" class="cls_007"><span class="cls_007"><Trigger Property="IsFocused" Value="True"></span></div>
<div style="position:absolute;left:142.94px;top:408.00px" class="cls_007"><span class="cls_007"><Trigger.EnterActions></span></div>
<div style="position:absolute;left:157.94px;top:421.50px" class="cls_007"><span class="cls_007"><PauseStoryboard BeginStoryboardName="GlowStoryboard"</span></div>
<div style="position:absolute;left:52.98px;top:435.00px" class="cls_007"><span class="cls_007">/></span></div>
<div style="position:absolute;left:142.94px;top:448.50px" class="cls_007"><span class="cls_007"></Trigger.EnterActions></span></div>
<div style="position:absolute;left:142.94px;top:462.00px" class="cls_007"><span class="cls_007"><Trigger.ExitActions></span></div>
<div style="position:absolute;left:157.94px;top:475.50px" class="cls_007"><span class="cls_007"><ResumeStoryboard</span></div>
<div style="position:absolute;left:52.98px;top:489.00px" class="cls_007"><span class="cls_007">BeginStoryboardName="GlowStoryboard" /></span></div>
<div style="position:absolute;left:142.94px;top:502.50px" class="cls_007"><span class="cls_007"></Trigger.ExitActions></span></div>
<div style="position:absolute;left:127.95px;top:516.00px" class="cls_007"><span class="cls_007"></Trigger></span></div>
<div style="position:absolute;left:127.95px;top:529.50px" class="cls_007"><span class="cls_007"><DataTrigger Binding="{Binding IsValid}" Value="True"></span></div>
<div style="position:absolute;left:142.94px;top:543.00px" class="cls_007"><span class="cls_007"><DataTrigger.EnterActions></span></div>
<div style="position:absolute;left:157.94px;top:556.50px" class="cls_007"><span class="cls_007"><StopStoryboard BeginStoryboardName="GlowStoryboard"</span></div>
<div style="position:absolute;left:52.98px;top:570.00px" class="cls_007"><span class="cls_007">/></span></div>
<div style="position:absolute;left:142.94px;top:583.50px" class="cls_007"><span class="cls_007"></DataTrigger.EnterActions></span></div>
<div style="position:absolute;left:127.95px;top:597.00px" class="cls_007"><span class="cls_007"></DataTrigger></span></div>
<div style="position:absolute;left:127.95px;top:610.50px" class="cls_007"><span class="cls_007"><EventTrigger RoutedEvent="Unloaded"></span></div>
<div style="position:absolute;left:142.94px;top:624.00px" class="cls_007"><span class="cls_007"><EventTrigger.Actions></span></div>
<div style="position:absolute;left:157.94px;top:637.50px" class="cls_007"><span class="cls_007"><RemoveStoryboard</span></div>
<div style="position:absolute;left:52.98px;top:651.00px" class="cls_007"><span class="cls_007">BeginStoryboardName="GlowStoryboard" /></span></div>
<div style="position:absolute;left:142.94px;top:664.50px" class="cls_007"><span class="cls_007"></EventTrigger.Actions></span></div>
<div style="position:absolute;left:127.95px;top:678.00px" class="cls_007"><span class="cls_007"></EventTrigger></span></div>
<div style="position:absolute;left:112.96px;top:691.50px" class="cls_007"><span class="cls_007"></Style.Triggers></span></div>
<div style="position:absolute;left:97.96px;top:705.00px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:82.97px;top:718.50px" class="cls_007"><span class="cls_007"></TextBox.Style></span></div>
<div style="position:absolute;left:67.97px;top:732.00px" class="cls_007"><span class="cls_007"></TextBox></span></div>
<div style="position:absolute;left:67.97px;top:745.50px" class="cls_007"><span class="cls_007"><TextBox Margin="20 0" /></span></div>
<div style="position:absolute;left:52.98px;top:759.00px" class="cls_007"><span class="cls_007"></StackPanel></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:196490px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background247.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:9.00px" class="cls_004"><span class="cls_004">This example has two textboxes, with the lower one existing solely to enable us to remove</span></div>
<div style="position:absolute;left:5.00px;top:27.00px" class="cls_004"><span class="cls_004">focus from the first one. The first textbox is data bound to a </span><span class="cls_007">Name</span><span class="cls_004"> property in our View</span></div>
<div style="position:absolute;left:5.00px;top:45.00px" class="cls_004"><span class="cls_004">Model. Let's imagine that we have some validation code that will update a property named</span></div>
<div style="position:absolute;left:5.00px;top:63.00px" class="cls_007"><span class="cls_007">IsValid</span><span class="cls_004"> when the </span><span class="cls_007">Name</span><span class="cls_004"> property is changed. We'll cover validation in depth in </span><span class="cls_015">Chapter 8</span><span class="cls_004">,</span></div>
<div style="position:absolute;left:5.00px;top:81.00px" class="cls_006"><span class="cls_006">Implementing Responsive Data Validation</span><span class="cls_004">, but for now, let's keep it simple.</span></div>
<div style="position:absolute;left:52.98px;top:105.00px" class="cls_007"><span class="cls_007">private string name = string.Empty;</span></div>
<div style="position:absolute;left:52.98px;top:118.50px" class="cls_007"><span class="cls_007">private bool isValid = false;</span></div>
<div style="position:absolute;left:52.98px;top:172.50px" class="cls_007"><span class="cls_007">public string Name</span></div>
<div style="position:absolute;left:52.98px;top:186.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:199.50px" class="cls_007"><span class="cls_007">get { return name; }</span></div>
<div style="position:absolute;left:67.97px;top:213.00px" class="cls_007"><span class="cls_007">set</span></div>
<div style="position:absolute;left:67.97px;top:226.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:240.00px" class="cls_007"><span class="cls_007">if (name != value)</span></div>
<div style="position:absolute;left:82.97px;top:253.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:267.00px" class="cls_007"><span class="cls_007">name = value;</span></div>
<div style="position:absolute;left:97.96px;top:280.50px" class="cls_007"><span class="cls_007">NotifyPropertyChanged();</span></div>
<div style="position:absolute;left:97.96px;top:294.00px" class="cls_007"><span class="cls_007">if (name.Length > 2) IsValid = true;</span></div>
<div style="position:absolute;left:82.97px;top:307.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:321.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:334.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:361.50px" class="cls_007"><span class="cls_007">public bool IsValid</span></div>
<div style="position:absolute;left:52.98px;top:375.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:388.50px" class="cls_007"><span class="cls_007">get { return isValid; }</span></div>
<div style="position:absolute;left:67.97px;top:402.00px" class="cls_007"><span class="cls_007">set { if (isValid != value) { isValid = value;</span></div>
<div style="position:absolute;left:82.97px;top:415.50px" class="cls_007"><span class="cls_007">NotifyPropertyChanged(); } }</span></div>
<div style="position:absolute;left:52.98px;top:429.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:449.25px" class="cls_004"><span class="cls_004">Here, we simply verify that the </span><span class="cls_007">Name</span><span class="cls_004"> property has a value that has three or more characters</span></div>
<div style="position:absolute;left:5.00px;top:467.25px" class="cls_004"><span class="cls_004">in it. The basic idea in this example is that we have an animation that highlights the fact that</span></div>
<div style="position:absolute;left:5.00px;top:485.25px" class="cls_004"><span class="cls_004">a particular form field requires a valid value.</span></div>
<div style="position:absolute;left:5.00px;top:503.25px" class="cls_004"><span class="cls_004">It could be a shaking, or growing and shrinking of the form field, or the animation of an</span></div>
<div style="position:absolute;left:5.00px;top:521.25px" class="cls_004"><span class="cls_004">adjacent element, but in our case, we have used a </span><span class="cls_007">DropShadowEffect</span><span class="cls_004"> element to create a</span></div>
<div style="position:absolute;left:5.00px;top:539.25px" class="cls_004"><span class="cls_004">glowing effect around it.</span></div>
<div style="position:absolute;left:5.00px;top:557.25px" class="cls_004"><span class="cls_004">In the </span><span class="cls_007">Triggers</span><span class="cls_004"> collection of our style, we have declared a number of triggers. The first one</span></div>
<div style="position:absolute;left:5.00px;top:575.25px" class="cls_004"><span class="cls_004">is a </span><span class="cls_007">DataTrigger</span><span class="cls_004"> and it data binds to the </span><span class="cls_007">IsValid</span><span class="cls_004"> property in the View Model and uses the</span></div>
<div style="position:absolute;left:5.00px;top:593.25px" class="cls_007"><span class="cls_007">BeginStoryboard</span><span class="cls_004"> trigger action element named </span><span class="cls_007">GlowStoryboard</span><span class="cls_004"> to make the glowing effect</span></div>
<div style="position:absolute;left:5.00px;top:611.25px" class="cls_004"><span class="cls_004">around the textbox grow and shrink when the property value is </span><span class="cls_007">false</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:629.25px" class="cls_004"><span class="cls_004">While animations are great at attracting the eye, they can also be quite distracting. Skipping</span></div>
<div style="position:absolute;left:5.00px;top:647.25px" class="cls_004"><span class="cls_004">over the </span><span class="cls_007">MultiDataTrigger</span><span class="cls_004"> momentarily, our animation will therefore be paused when the</span></div>
<div style="position:absolute;left:5.00px;top:665.25px" class="cls_004"><span class="cls_004">textbox is focused, so that the user can enter the details without distraction. We achieve</span></div>
<div style="position:absolute;left:5.00px;top:683.25px" class="cls_004"><span class="cls_004">this by declaring a </span><span class="cls_007">PauseStoryboard</span><span class="cls_004"> action in the trigger with the condition that the</span></div>
<div style="position:absolute;left:5.00px;top:701.25px" class="cls_007"><span class="cls_007">IsFocused</span><span class="cls_004"> property is </span><span class="cls_007">true</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:719.25px" class="cls_004"><span class="cls_004">Using the </span><span class="cls_007">EnterActions</span><span class="cls_004"> collection of the trigger ensures that the </span><span class="cls_007">PauseStoryboard</span><span class="cls_004"> action is</span></div>
<div style="position:absolute;left:5.00px;top:737.25px" class="cls_004"><span class="cls_004">run as the </span><span class="cls_007">IsFocused</span><span class="cls_004"> property is set to </span><span class="cls_007">true</span><span class="cls_004">. Declaring the </span><span class="cls_007">ResumeStoryboard</span><span class="cls_004"> action in the</span></div>
<div style="position:absolute;left:5.00px;top:755.25px" class="cls_007"><span class="cls_007">ExitActions</span><span class="cls_004"> collection of the trigger ensures that it will be run as the </span><span class="cls_007">IsFocused</span><span class="cls_004"> property is</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:197292px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background248.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">set to </span><span class="cls_007">false</span><span class="cls_004">, or in other words, when the control loses focus.</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">When the user has entered a value, our View Model validates whether the provided value is</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">indeed valid and if so, it sets the </span><span class="cls_007">IsValid</span><span class="cls_004"> property to </span><span class="cls_007">true</span><span class="cls_004">. In our example, we just verify</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">that the entered string contains three or more characters in order for it to be valid. Setting</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">UpdateSourceTrigger</span><span class="cls_004"> property to </span><span class="cls_007">PropertyChanged</span><span class="cls_004"> on the binding ensures this</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">validation occurs on each keystroke.</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">Our example uses a </span><span class="cls_007">DataTrigger</span><span class="cls_004"> to data bind to this property and when it is </span><span class="cls_007">true</span><span class="cls_004">, it</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">triggers the </span><span class="cls_007">StopStoryboard</span><span class="cls_004"> action, which stops the storyboard from running any further. As</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">FillBehavior</span><span class="cls_004"> property of our storyboard is not explicitly set, it will default to the </span><span class="cls_007">Stop</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">value and the animated property value will return to the original value that it had prior to</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">being animated.</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">However, what should happen if the user entered three or more characters and then</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">deleted them? The data trigger would trigger the </span><span class="cls_007">StopStoryboard</span><span class="cls_004"> action and the storyboard</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">would be stopped. As they deleted the characters and the </span><span class="cls_007">IsValid</span><span class="cls_004"> property would be set</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">to </span><span class="cls_007">false</span><span class="cls_004"> and the condition of the first </span><span class="cls_007">DataTrigger</span><span class="cls_004"> would then trigger the initial</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_007"><span class="cls_007">BeginStoryboard</span><span class="cls_004"> action to start the storyboard again.</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">But this would occur while the focus was still on the textbox and while the animation on the</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">effect should not be running. It is for this reason that we declared the </span><span class="cls_007">MultiDataTrigger</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_004"><span class="cls_004">element that we skipped over earlier. In this trigger, we have two conditions. One is that the</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_007"><span class="cls_007">IsFocused</span><span class="cls_004"> property should be </span><span class="cls_007">true</span><span class="cls_004"> and for this alone, we could have used a </span><span class="cls_007">MultiTrigger</span></div>
<div style="position:absolute;left:5.00px;top:363.75px" class="cls_004"><span class="cls_004">instead.</span></div>
<div style="position:absolute;left:5.00px;top:381.75px" class="cls_004"><span class="cls_004">However, the other condition requires that we data bind to the </span><span class="cls_007">IsValid</span><span class="cls_004"> property from the</span></div>
<div style="position:absolute;left:5.00px;top:399.75px" class="cls_004"><span class="cls_004">View Model and for that, we need to use the </span><span class="cls_007">MultiDataTrigger</span><span class="cls_004"> element. So, this trigger</span></div>
<div style="position:absolute;left:5.00px;top:417.75px" class="cls_004"><span class="cls_004">will run its </span><span class="cls_007">PauseStoryboard</span><span class="cls_004"> action when the textbox is focused and as soon as the data</span></div>
<div style="position:absolute;left:5.00px;top:435.75px" class="cls_004"><span class="cls_004">bound value becomes invalid, or in other words, as the user deletes the third character.</span></div>
<div style="position:absolute;left:5.00px;top:453.75px" class="cls_004"><span class="cls_004">The triggers are evaluated from top to bottom in the declared order in the XAML and as the</span></div>
<div style="position:absolute;left:5.00px;top:471.75px" class="cls_004"><span class="cls_004">user deletes the third character, the first trigger begins the animation. The</span></div>
<div style="position:absolute;left:5.00px;top:489.75px" class="cls_007"><span class="cls_007">MultiDataTrigger</span><span class="cls_004"> has to be declared after the first trigger, so that the storyboard will be</span></div>
<div style="position:absolute;left:5.00px;top:507.75px" class="cls_004"><span class="cls_004">started before it pauses it. In this case, the glow effect will start again once the user has</span></div>
<div style="position:absolute;left:5.00px;top:525.75px" class="cls_004"><span class="cls_004">moved focus from the first textbox as required.</span></div>
<div style="position:absolute;left:5.00px;top:543.75px" class="cls_004"><span class="cls_004">Finally, this example demonstrates how we can use a </span><span class="cls_007">RemoveStoryboard</span><span class="cls_004"> trigger action to</span></div>
<div style="position:absolute;left:5.00px;top:561.75px" class="cls_004"><span class="cls_004">remove the storyboard when it is no longer needed, freeing up its resources. The usual way</span></div>
<div style="position:absolute;left:5.00px;top:579.75px" class="cls_004"><span class="cls_004">to do this is by utilizing an </span><span class="cls_007">EventTrigger</span><span class="cls_004"> in the </span><span class="cls_007">Unloaded</span><span class="cls_004"> event of the relevant control.</span></div>
<div style="position:absolute;left:5.00px;top:597.75px" class="cls_004"><span class="cls_004">While these are the only trigger action elements that control the running state of their</span></div>
<div style="position:absolute;left:5.00px;top:615.75px" class="cls_004"><span class="cls_004">associated storyboard elements, there are a further three actions that can control other</span></div>
<div style="position:absolute;left:5.00px;top:633.75px" class="cls_004"><span class="cls_004">aspects of, or set other properties of the storyboard.</span></div>
<div style="position:absolute;left:5.00px;top:651.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">SetStoryboardSpeedRatio</span><span class="cls_004"> trigger action can set the </span><span class="cls_007">SpeedRatio</span><span class="cls_004"> of the associated</span></div>
<div style="position:absolute;left:5.00px;top:669.75px" class="cls_004"><span class="cls_004">storyboard. We specify the desired ratio in its </span><span class="cls_007">SpeedRatio</span><span class="cls_004"> property and this value will be</span></div>
<div style="position:absolute;left:5.00px;top:687.75px" class="cls_004"><span class="cls_004">applied when the action's related trigger condition is met. Note that this element can only</span></div>
<div style="position:absolute;left:5.00px;top:705.75px" class="cls_004"><span class="cls_004">work on a storyboard that has already been started, although it can work at any time after</span></div>
<div style="position:absolute;left:5.00px;top:723.75px" class="cls_004"><span class="cls_004">this point.</span></div>
<div style="position:absolute;left:5.00px;top:741.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">SkipStoryboardToFill</span><span class="cls_004"> trigger action will move the current position of a storyboard to</span></div>
<div style="position:absolute;left:5.00px;top:759.75px" class="cls_004"><span class="cls_004">its fill period, if it has one. Remember that the </span><span class="cls_007">FillBehavior</span><span class="cls_004"> property determines what</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:198094px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background249.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">should happen during the fill period. If the storyboard has child timelines, then their positions</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">will also be forwarded to their fill periods at this point.</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">Last, but not least, there is a </span><span class="cls_007">SeekStoryboard</span><span class="cls_004"> trigger action, which enables us to move the</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">current position of storyboard to a location, relative to the position specified by the </span><span class="cls_007">Origin</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">property, which has a begin time of zero seconds by default. When declaring the</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_007"><span class="cls_007">SeekStoryboard</span><span class="cls_004"> action, we specify the desired seek position in the </span><span class="cls_007">Offset</span><span class="cls_004"> property and</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">optionally set the </span><span class="cls_007">Origin</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">Offset</span><span class="cls_004"> property is of type </span><span class="cls_007">TimeSpan</span><span class="cls_004"> and we can use the time notation highlighted</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">earlier to specify its value in XAML. The </span><span class="cls_007">Origin</span><span class="cls_004"> property is of type </span><span class="cls_007">TimeSeekOrigin</span><span class="cls_004"> and we</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">can specify one of two values.</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">The first is the default value of </span><span class="cls_007">BeginTime</span><span class="cls_004">, which places the origin at the start of the</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">timeline, while the second is </span><span class="cls_007">Duration</span><span class="cls_004">, which places it at the end of a single iteration of the</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">timeline's natural duration. Note that the various speed ratio values are not taken into</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">consideration when seeking through a timeline's duration.</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">That completes our look at the range of trigger actions that we can use to control our</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">storyboards. Each of these trigger actions have corresponding methods in the </span><span class="cls_007">Storyboard</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">class that they call when their related trigger conditions are met.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:198896px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background250.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_008"><span class="cls_008">Easing functions</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">When declaring animations with WPF, we are able to utilize a powerful capability that helps</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">us to define more specialized animations. While we normally provide a start and end value</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">for our animations and let WPF interpolate the intermediate values, there is a way that we</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">can affect this interpolation process.</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">There are a number of mathematical functions that provide complex animation paths and</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">are known as easing functions. For example, these can accurately replicate the movement</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">of a spring, or the bounce of a ball.</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">We can simply declare the appropriate easing function within the </span><span class="cls_007">EasingFunction</span><span class="cls_004"> property</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">of the animation. Each easing function extends the </span><span class="cls_007">EasingFunctionBase</span><span class="cls_004"> class and has its</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">own specific properties. For example, the </span><span class="cls_007">BounceEase</span><span class="cls_004"> element provides </span><span class="cls_007">Bounces</span><span class="cls_004"> and</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_007"><span class="cls_007">Bounciness</span><span class="cls_004"> properties, while the </span><span class="cls_007">ElasticEase</span><span class="cls_004"> class declare the </span><span class="cls_007">Oscillations</span><span class="cls_004"> and</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_007"><span class="cls_007">Springiness</span><span class="cls_004"> properties.</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">All easing functions inherit the </span><span class="cls_007">EasingMode</span><span class="cls_004"> property from the base class. This property is of</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">the enumeration type </span><span class="cls_007">EasingMode</span><span class="cls_004"> and gives us three options. The </span><span class="cls_007">EaseIn</span><span class="cls_004"> option follows the</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">normal mathematical formula associated with each easing function. The </span><span class="cls_007">EaseOut</span><span class="cls_004"> option</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">uses the inverse of the mathematical formula.</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">EaseInOut</span><span class="cls_004"> option uses the standard formula for the first half and the inverse formula for</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_004"><span class="cls_004">the second half. While not strictly true, this can be somewhat thought of as </span><span class="cls_007">EaseIn</span><span class="cls_004"> affects</span></div>
<div style="position:absolute;left:5.00px;top:363.75px" class="cls_004"><span class="cls_004">the start of the animation, </span><span class="cls_007">EaseOut</span><span class="cls_004"> affects the end of the animation and </span><span class="cls_007">EaseInOut</span><span class="cls_004"> affects</span></div>
<div style="position:absolute;left:5.00px;top:381.75px" class="cls_004"><span class="cls_004">both the start and the end of the animation. Let's see an example of a bouncing ball</span></div>
<div style="position:absolute;left:5.00px;top:399.75px" class="cls_004"><span class="cls_004">animation to demonstrate this ability.</span></div>
<div style="position:absolute;left:52.98px;top:423.00px" class="cls_007"><span class="cls_007"><Canvas></span></div>
<div style="position:absolute;left:67.97px;top:436.50px" class="cls_007"><span class="cls_007"><Ellipse Width="50" Height="50" Fill="Orange" Stroke="Black"</span></div>
<div style="position:absolute;left:82.97px;top:450.00px" class="cls_007"><span class="cls_007">StrokeThickness="3"></span></div>
<div style="position:absolute;left:82.97px;top:463.50px" class="cls_007"><span class="cls_007"><Ellipse.Triggers></span></div>
<div style="position:absolute;left:97.96px;top:477.00px" class="cls_007"><span class="cls_007"><EventTrigger RoutedEvent="Loaded"></span></div>
<div style="position:absolute;left:112.96px;top:490.50px" class="cls_007"><span class="cls_007"><BeginStoryboard></span></div>
<div style="position:absolute;left:127.95px;top:504.00px" class="cls_007"><span class="cls_007"><Storyboard RepeatBehavior="Forever"></span></div>
<div style="position:absolute;left:142.94px;top:517.50px" class="cls_007"><span class="cls_007"><Storyboard Storyboard.TargetProperty="(Canvas.Top)"></span></div>
<div style="position:absolute;left:157.94px;top:531.00px" class="cls_007"><span class="cls_007"><DoubleAnimation Duration="00:00:3" From="0"</span></div>
<div style="position:absolute;left:52.98px;top:544.50px" class="cls_007"><span class="cls_007">To="200"></span></div>
<div style="position:absolute;left:172.93px;top:558.00px" class="cls_007"><span class="cls_007"><DoubleAnimation.EasingFunction></span></div>
<div style="position:absolute;left:187.92px;top:571.50px" class="cls_007"><span class="cls_007"><BounceEase EasingMode="EaseOut" Bounces="10"</span></div>
<div style="position:absolute;left:202.92px;top:585.00px" class="cls_007"><span class="cls_007">Bounciness="1.5" /></span></div>
<div style="position:absolute;left:172.93px;top:598.50px" class="cls_007"><span class="cls_007"></DoubleAnimation.EasingFunction></span></div>
<div style="position:absolute;left:157.94px;top:612.00px" class="cls_007"><span class="cls_007"></DoubleAnimation></span></div>
<div style="position:absolute;left:142.94px;top:625.50px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:142.94px;top:639.00px" class="cls_007"><span class="cls_007"><Storyboard Storyboard.TargetProperty="(Canvas.Left)"></span></div>
<div style="position:absolute;left:157.94px;top:652.50px" class="cls_007"><span class="cls_007"><DoubleAnimation Duration="00:00:3.5" From="0"</span></div>
<div style="position:absolute;left:52.98px;top:666.00px" class="cls_007"><span class="cls_007">To="200"</span></div>
<div style="position:absolute;left:172.93px;top:679.50px" class="cls_007"><span class="cls_007">DecelerationRatio="0.2" /></span></div>
<div style="position:absolute;left:142.94px;top:693.00px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:127.95px;top:706.50px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:112.96px;top:720.00px" class="cls_007"><span class="cls_007"></BeginStoryboard></span></div>
<div style="position:absolute;left:97.96px;top:733.50px" class="cls_007"><span class="cls_007"></EventTrigger></span></div>
<div style="position:absolute;left:82.97px;top:747.00px" class="cls_007"><span class="cls_007"></Ellipse.Triggers></span></div>
<div style="position:absolute;left:67.97px;top:760.50px" class="cls_007"><span class="cls_007"></Ellipse></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:199698px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background251.jpg" width=612 height=792></div>
<div style="position:absolute;left:67.97px;top:3.00px" class="cls_007"><span class="cls_007"><Line Canvas.Top="250" Canvas.Left="25" X1="0" Y1="1.5" X2="225"</span></div>
<div style="position:absolute;left:52.98px;top:16.50px" class="cls_007"><span class="cls_007">Y2="1.5"</span></div>
<div style="position:absolute;left:82.97px;top:30.00px" class="cls_007"><span class="cls_007">Stroke="Black" StrokeThickness="3" /></span></div>
<div style="position:absolute;left:52.98px;top:43.50px" class="cls_007"><span class="cls_007"></Canvas></span></div>
<div style="position:absolute;left:5.00px;top:63.75px" class="cls_004"><span class="cls_004">Here, we have a </span><span class="cls_007">Canvas</span><span class="cls_004"> panel that contains two shapes; an ellipse and a line. The line is</span></div>
<div style="position:absolute;left:5.00px;top:81.75px" class="cls_004"><span class="cls_004">simply to give the impression of the ground. The </span><span class="cls_007">Ellipse</span><span class="cls_004"> element defines some basic</span></div>
<div style="position:absolute;left:5.00px;top:99.75px" class="cls_004"><span class="cls_004">appearance properties and then an </span><span class="cls_007">EventTrigger</span><span class="cls_004"> element that starts our eased animation</span></div>
<div style="position:absolute;left:5.00px;top:117.75px" class="cls_004"><span class="cls_004">when the shape object is loaded. We have an outer </span><span class="cls_007">Storyboard</span><span class="cls_004"> element that is set to</span></div>
<div style="position:absolute;left:5.00px;top:135.75px" class="cls_004"><span class="cls_004">repeat forever and contains two inner storyboards.</span></div>
<div style="position:absolute;left:5.00px;top:153.75px" class="cls_004"><span class="cls_004">The first of these inner storyboards targets the </span><span class="cls_007">Canvas.Top</span><span class="cls_004"> Attached Property using the</span></div>
<div style="position:absolute;left:5.00px;top:171.75px" class="cls_007"><span class="cls_007">Storyboard.TargetProperty</span><span class="cls_004">, while the second targets its </span><span class="cls_007">Canvas.Left</span><span class="cls_004"> Attached Property.</span></div>
<div style="position:absolute;left:5.00px;top:189.75px" class="cls_004"><span class="cls_004">Note that we do not need to specify the </span><span class="cls_007">Storyboard.TargetProperty</span><span class="cls_004"> value here, as the</span></div>
<div style="position:absolute;left:5.00px;top:207.75px" class="cls_004"><span class="cls_004">storyboard resides within the target element, which will be implicitly set as the target for us.</span></div>
<div style="position:absolute;left:5.00px;top:225.75px" class="cls_004"><span class="cls_004">Also, remember that we need to wrap the Attached Property name with its class name in</span></div>
<div style="position:absolute;left:5.00px;top:243.75px" class="cls_004"><span class="cls_004">brackets for this to work.</span></div>
<div style="position:absolute;left:5.00px;top:261.75px" class="cls_004"><span class="cls_004">The first storyboard is responsible for the vertical movement of our ball and so this is the</span></div>
<div style="position:absolute;left:5.00px;top:279.75px" class="cls_004"><span class="cls_004">animation that we want to use the </span><span class="cls_007">BounceEase</span><span class="cls_004"> function with. In order to utilize this</span></div>
<div style="position:absolute;left:5.00px;top:297.75px" class="cls_004"><span class="cls_004">functionality, we simply declare the </span><span class="cls_007">BounceEase</span><span class="cls_004"> object within the</span></div>
<div style="position:absolute;left:5.00px;top:315.75px" class="cls_007"><span class="cls_007">DoubleAnimation.EasingFunction</span><span class="cls_004"> property and set the desired property values.</span></div>
<div style="position:absolute;left:5.00px;top:333.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">Bounces</span><span class="cls_004"> property determines how many times the ball should bounce, or rebound off</span></div>
<div style="position:absolute;left:5.00px;top:351.75px" class="cls_004"><span class="cls_004">the lower extent of the animation. Note that this does not include the final half-bounce that</span></div>
<div style="position:absolute;left:5.00px;top:369.75px" class="cls_004"><span class="cls_004">this easing function will perform. The </span><span class="cls_007">Bounciness</span><span class="cls_004"> property specifies how bouncy the ball is.</span></div>
<div style="position:absolute;left:5.00px;top:387.75px" class="cls_004"><span class="cls_004">Strangely, the higher this value is, the less bouncy the ball will be. Also note that this value</span></div>
<div style="position:absolute;left:5.00px;top:405.75px" class="cls_004"><span class="cls_004">must be positive.</span></div>
<div style="position:absolute;left:5.00px;top:423.75px" class="cls_004"><span class="cls_004">As physics determines that the horizontal velocity of the ball should remain constant for the</span></div>
<div style="position:absolute;left:5.00px;top:441.75px" class="cls_004"><span class="cls_004">most part, we do not need to apply an easing function to the second animation. Instead, we</span></div>
<div style="position:absolute;left:5.00px;top:459.75px" class="cls_004"><span class="cls_004">have added a small value for its </span><span class="cls_007">DecelerationRatio</span><span class="cls_004"> property, which nicely simulates the</span></div>
<div style="position:absolute;left:5.00px;top:477.75px" class="cls_004"><span class="cls_004">sideways friction on the ball.</span></div>
<div style="position:absolute;left:5.00px;top:495.75px" class="cls_004"><span class="cls_004">As can be seen, it is very easy to take advantage of these mathematical formulae to greatly</span></div>
<div style="position:absolute;left:5.00px;top:513.75px" class="cls_004"><span class="cls_004">increase the movement of our animations. While there is not enough space in this book for</span></div>
<div style="position:absolute;left:5.00px;top:531.75px" class="cls_004"><span class="cls_004">us to cover all of these easing functions, it is well worth investigating them yourselves. Let's</span></div>
<div style="position:absolute;left:5.00px;top:549.75px" class="cls_004"><span class="cls_004">take a look at another example, to see how we can simulate the movement of a spring</span></div>
<div style="position:absolute;left:5.00px;top:567.75px" class="cls_004"><span class="cls_004">using the </span><span class="cls_007">ElasticEase</span><span class="cls_004"> class:</span></div>
<div style="position:absolute;left:52.98px;top:591.00px" class="cls_007"><span class="cls_007"><Rectangle Canvas.Top="250" Canvas.Left="25" Width="25" Height="50"</span></div>
<div style="position:absolute;left:67.97px;top:604.50px" class="cls_007"><span class="cls_007">Fill="Orange" Stroke="Black" StrokeThickness="3"></span></div>
<div style="position:absolute;left:67.97px;top:618.00px" class="cls_007"><span class="cls_007"><Rectangle.Triggers></span></div>
<div style="position:absolute;left:82.97px;top:631.50px" class="cls_007"><span class="cls_007"><EventTrigger RoutedEvent="Loaded"></span></div>
<div style="position:absolute;left:97.96px;top:645.00px" class="cls_007"><span class="cls_007"><BeginStoryboard></span></div>
<div style="position:absolute;left:112.96px;top:658.50px" class="cls_007"><span class="cls_007"><Storyboard RepeatBehavior="Forever"></span></div>
<div style="position:absolute;left:127.95px;top:672.00px" class="cls_007"><span class="cls_007"><Storyboard Storyboard.TargetProperty="Height"></span></div>
<div style="position:absolute;left:142.94px;top:685.50px" class="cls_007"><span class="cls_007"><DoubleAnimation Duration="00:00:3" From="50" To="200"></span></div>
<div style="position:absolute;left:157.94px;top:699.00px" class="cls_007"><span class="cls_007"><DoubleAnimation.EasingFunction></span></div>
<div style="position:absolute;left:172.93px;top:712.50px" class="cls_007"><span class="cls_007"><ElasticEase EasingMode="EaseOut" Oscillations="6"</span></div>
<div style="position:absolute;left:187.92px;top:726.00px" class="cls_007"><span class="cls_007">Springiness="2" /></span></div>
<div style="position:absolute;left:157.94px;top:739.50px" class="cls_007"><span class="cls_007"></DoubleAnimation.EasingFunction></span></div>
<div style="position:absolute;left:142.94px;top:753.00px" class="cls_007"><span class="cls_007"></DoubleAnimation></span></div>
<div style="position:absolute;left:127.95px;top:766.50px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:200500px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background252.jpg" width=612 height=792></div>
<div style="position:absolute;left:112.96px;top:3.00px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:97.96px;top:16.50px" class="cls_007"><span class="cls_007"></BeginStoryboard></span></div>
<div style="position:absolute;left:82.97px;top:30.00px" class="cls_007"><span class="cls_007"></EventTrigger></span></div>
<div style="position:absolute;left:67.97px;top:43.50px" class="cls_007"><span class="cls_007"></Rectangle.Triggers></span></div>
<div style="position:absolute;left:52.98px;top:57.00px" class="cls_007"><span class="cls_007"></Rectangle></span></div>
<div style="position:absolute;left:5.00px;top:90.00px" class="cls_004"><span class="cls_004">In this example, we have a thin </span><span class="cls_007">Rectangle</span><span class="cls_004"> element that simulates the movement of a coiled</span></div>
<div style="position:absolute;left:5.00px;top:108.00px" class="cls_004"><span class="cls_004">spring using an </span><span class="cls_007">ElasticEase</span><span class="cls_004"> function. The </span><span class="cls_007">Oscillations</span><span class="cls_004"> property specifies the number of</span></div>
<div style="position:absolute;left:5.00px;top:126.00px" class="cls_004"><span class="cls_004">times that the rectangle will grow and shrink over the lifetime of the animation effect and the</span></div>
<div style="position:absolute;left:5.00px;top:144.00px" class="cls_007"><span class="cls_007">Springiness</span><span class="cls_004"> property determines the stiffness of the spring, where larger values equal</span></div>
<div style="position:absolute;left:5.00px;top:162.00px" class="cls_004"><span class="cls_004">more springiness.</span></div>
<div style="position:absolute;left:5.00px;top:180.00px" class="cls_004"><span class="cls_004">While the two demonstrated easing functions are rather specialized and unsuitable to use in</span></div>
<div style="position:absolute;left:5.00px;top:198.00px" class="cls_004"><span class="cls_004">many cases, the vast majority of the remaining functions are all variations on standard</span></div>
<div style="position:absolute;left:5.00px;top:216.00px" class="cls_004"><span class="cls_004">circular, or exponential curves, or curves that use the formula </span><span class="cls_006">f(t) = t</span><span class="cls_014"><sup>n</sup></span><span class="cls_004">, where </span><span class="cls_006">n</span><span class="cls_004"> is either</span></div>
<div style="position:absolute;left:5.00px;top:236.25px" class="cls_004"><span class="cls_004">determined by the exact easing function used, or by the </span><span class="cls_007">Power</span><span class="cls_004"> property of the </span><span class="cls_007">PowerEase</span></div>
<div style="position:absolute;left:5.00px;top:254.25px" class="cls_004"><span class="cls_004">function.</span></div>
<div style="position:absolute;left:5.00px;top:272.25px" class="cls_004"><span class="cls_004">For example, the </span><span class="cls_007">QuadraticEase</span><span class="cls_004"> function uses the formula </span><span class="cls_006">f(t) = t</span><span class="cls_014"><sup>2</sup></span><span class="cls_004">, the </span><span class="cls_007">CubicEase</span><span class="cls_004"> function</span></div>
<div style="position:absolute;left:5.00px;top:292.50px" class="cls_004"><span class="cls_004">uses the formula </span><span class="cls_006">f(t) = t</span><span class="cls_014"><sup>3</sup></span><span class="cls_004">, the </span><span class="cls_007">QuarticEase</span><span class="cls_004"> function uses the formula </span><span class="cls_006">f(t) = t</span><span class="cls_014"><sup>4</sup></span><span class="cls_004">, the</span></div>
<div style="position:absolute;left:5.00px;top:312.75px" class="cls_007"><span class="cls_007">QuinticEase</span><span class="cls_004"> function uses the formula </span><span class="cls_006">f(t) = t</span><span class="cls_014"><sup>5</sup></span><span class="cls_004">, while the </span><span class="cls_007">PowerEase</span><span class="cls_004"> function uses the</span></div>
<div style="position:absolute;left:5.00px;top:333.00px" class="cls_004"><span class="cls_004">formula </span><span class="cls_006">f(t) = t</span><span class="cls_014"><sup>n</sup></span><span class="cls_004">, where </span><span class="cls_006">n</span><span class="cls_004"> is determined by its </span><span class="cls_007">Power</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:5.00px;top:353.25px" class="cls_004"><span class="cls_004">Apart from these variations of the standard acceleration/deceleration curve, there is one</span></div>
<div style="position:absolute;left:5.00px;top:371.25px" class="cls_004"><span class="cls_004">final useful easing function named </span><span class="cls_007">BackEase</span><span class="cls_004">. This has the effect of overshooting its starting</span></div>
<div style="position:absolute;left:5.00px;top:389.25px" class="cls_004"><span class="cls_004">or ending </span><span class="cls_007">From</span><span class="cls_004"> or </span><span class="cls_007">To</span><span class="cls_004"> values, dependent upon the value of the </span><span class="cls_007">EasingMode</span><span class="cls_004"> property, and then</span></div>
<div style="position:absolute;left:5.00px;top:407.25px" class="cls_004"><span class="cls_004">reversing back to it. This is one of the more usable easing functions, so let's see an</span></div>
<div style="position:absolute;left:5.00px;top:425.25px" class="cls_004"><span class="cls_004">example of a </span><span class="cls_007">TextBox</span><span class="cls_004"> element sliding on screen.</span></div>
<div style="position:absolute;left:52.98px;top:448.50px" class="cls_007"><span class="cls_007"><Canvas ClipToBounds="True"></span></div>
<div style="position:absolute;left:67.97px;top:462.00px" class="cls_007"><span class="cls_007"><TextBox Canvas.Top="50" Canvas.Left="-150" Width="150"</span></div>
<div style="position:absolute;left:52.98px;top:475.50px" class="cls_007"><span class="cls_007">Height="25"></span></div>
<div style="position:absolute;left:82.97px;top:489.00px" class="cls_007"><span class="cls_007"><TextBox.Triggers></span></div>
<div style="position:absolute;left:97.96px;top:502.50px" class="cls_007"><span class="cls_007"><EventTrigger RoutedEvent="Loaded"></span></div>
<div style="position:absolute;left:112.96px;top:516.00px" class="cls_007"><span class="cls_007"><BeginStoryboard></span></div>
<div style="position:absolute;left:127.95px;top:529.50px" class="cls_007"><span class="cls_007"><Storyboard Storyboard.TargetProperty="(Canvas.Left)"</span></div>
<div style="position:absolute;left:142.94px;top:543.00px" class="cls_007"><span class="cls_007">Duration="00:00:2" RepeatBehavior="Forever"></span></div>
<div style="position:absolute;left:142.94px;top:556.50px" class="cls_007"><span class="cls_007"><DoubleAnimation Duration="00:00:1" From="-150"</span></div>
<div style="position:absolute;left:52.98px;top:570.00px" class="cls_007"><span class="cls_007">To="50"></span></div>
<div style="position:absolute;left:157.94px;top:583.50px" class="cls_007"><span class="cls_007"><DoubleAnimation.EasingFunction></span></div>
<div style="position:absolute;left:172.93px;top:597.00px" class="cls_007"><span class="cls_007"><BackEase EasingMode="EaseOut" Amplitude="0.75" /></span></div>
<div style="position:absolute;left:157.94px;top:610.50px" class="cls_007"><span class="cls_007"></DoubleAnimation.EasingFunction></span></div>
<div style="position:absolute;left:142.94px;top:624.00px" class="cls_007"><span class="cls_007"></DoubleAnimation></span></div>
<div style="position:absolute;left:127.95px;top:637.50px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:112.96px;top:651.00px" class="cls_007"><span class="cls_007"></BeginStoryboard></span></div>
<div style="position:absolute;left:97.96px;top:664.50px" class="cls_007"><span class="cls_007"></EventTrigger></span></div>
<div style="position:absolute;left:82.97px;top:678.00px" class="cls_007"><span class="cls_007"></TextBox.Triggers></span></div>
<div style="position:absolute;left:67.97px;top:691.50px" class="cls_007"><span class="cls_007"></TextBox></span></div>
<div style="position:absolute;left:52.98px;top:705.00px" class="cls_007"><span class="cls_007"></Canvas></span></div>
<div style="position:absolute;left:5.00px;top:725.25px" class="cls_004"><span class="cls_004">In this example, we start with a </span><span class="cls_007">Canvas</span><span class="cls_004"> object that has its </span><span class="cls_007">ClipToBounds</span><span class="cls_004"> property set to</span></div>
<div style="position:absolute;left:5.00px;top:743.25px" class="cls_007"><span class="cls_007">true</span><span class="cls_004">. This ensures that elements that are outside the bounds of the canvas will not be</span></div>
<div style="position:absolute;left:5.00px;top:761.25px" class="cls_004"><span class="cls_004">visible. Inside the canvas, we have declared a </span><span class="cls_007">TextBox</span><span class="cls_004"> control that is initially placed totally</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:201302px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background253.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">outside the bounds of the canvas and so it will be invisible.</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">When the control is loaded, the </span><span class="cls_007">EventTrigger</span><span class="cls_004"> element will start the animation that targets</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">Canvas.Left</span><span class="cls_004"> Attached Property. Note that the duration on the storyboard is one second</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">longer than the duration on the animation and so the storyboard will wait for one second</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">after the animation has completed before restarting. This gives us time to appreciate the</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">effect of the applied easing function.</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">The animation will slide the textbox to its ending position from its initial off-screen position.</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">By using the </span><span class="cls_007">BackEase</span><span class="cls_004"> function, the textbox will slightly slide past its ending position and</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">then reverse back into it. The amount past its ending position that it will slide to is</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">determined by the value of its </span><span class="cls_007">Amplitude</span><span class="cls_004"> property, with higher values extending the</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">overshoot distance.</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">While we have only discussed using these easing functions with </span><span class="cls_007">From</span><span class="cls_004">, </span><span class="cls_007">By</span><span class="cls_004"> and </span><span class="cls_007">To</span><span class="cls_004"> animations</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">so far, it is also possible to use them with key-frame animations as well. There are a</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">number of classes that follow the </span><span class="cls_007">Easing<Type>KeyFrame</span><span class="cls_004"> naming convention, such as the</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_007"><span class="cls_007">EasingColorKeyFrame</span><span class="cls_004"> class. These classes have an </span><span class="cls_007">EasingFunction</span><span class="cls_004"> property that enables</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">us to specify which function to use.</span></div>
<div style="position:absolute;left:52.98px;top:297.00px" class="cls_007"><span class="cls_007"><TextBlock Text="The operation was successful" Margin="20"></span></div>
<div style="position:absolute;left:67.97px;top:310.50px" class="cls_007"><span class="cls_007"><TextBlock.Triggers></span></div>
<div style="position:absolute;left:82.97px;top:324.00px" class="cls_007"><span class="cls_007"><EventTrigger RoutedEvent="Loaded"></span></div>
<div style="position:absolute;left:97.96px;top:337.50px" class="cls_007"><span class="cls_007"><BeginStoryboard></span></div>
<div style="position:absolute;left:112.96px;top:351.00px" class="cls_007"><span class="cls_007"><Storyboard Storyboard.TargetProperty="FontSize"></span></div>
<div style="position:absolute;left:127.95px;top:364.50px" class="cls_007"><span class="cls_007"><DoubleAnimationUsingKeyFrames Duration="00:00:2.5"></span></div>
<div style="position:absolute;left:142.94px;top:378.00px" class="cls_007"><span class="cls_007"><DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="8" /></span></div>
<div style="position:absolute;left:142.94px;top:391.50px" class="cls_007"><span class="cls_007"><EasingDoubleKeyFrame KeyTime="0:0:1" Value="36"></span></div>
<div style="position:absolute;left:157.94px;top:405.00px" class="cls_007"><span class="cls_007"><EasingDoubleKeyFrame.EasingFunction></span></div>
<div style="position:absolute;left:172.93px;top:418.50px" class="cls_007"><span class="cls_007"><BounceEase EasingMode="EaseOut" Bounces="2"</span></div>
<div style="position:absolute;left:187.92px;top:432.00px" class="cls_007"><span class="cls_007">Bounciness="1.5" /></span></div>
<div style="position:absolute;left:157.94px;top:445.50px" class="cls_007"><span class="cls_007"></EasingDoubleKeyFrame.EasingFunction></span></div>
<div style="position:absolute;left:142.94px;top:459.00px" class="cls_007"><span class="cls_007"></EasingDoubleKeyFrame></span></div>
<div style="position:absolute;left:142.94px;top:472.50px" class="cls_007"><span class="cls_007"><EasingDoubleKeyFrame KeyTime="0:0:2" Value="8"></span></div>
<div style="position:absolute;left:157.94px;top:486.00px" class="cls_007"><span class="cls_007"><EasingDoubleKeyFrame.EasingFunction></span></div>
<div style="position:absolute;left:172.93px;top:499.50px" class="cls_007"><span class="cls_007"><ElasticEase EasingMode="EaseIn" Oscillations="2"</span></div>
<div style="position:absolute;left:187.92px;top:513.00px" class="cls_007"><span class="cls_007">Springiness="1.5" /></span></div>
<div style="position:absolute;left:157.94px;top:526.50px" class="cls_007"><span class="cls_007"></EasingDoubleKeyFrame.EasingFunction></span></div>
<div style="position:absolute;left:142.94px;top:540.00px" class="cls_007"><span class="cls_007"></EasingDoubleKeyFrame></span></div>
<div style="position:absolute;left:142.94px;top:553.50px" class="cls_007"><span class="cls_007"><EasingDoubleKeyFrame KeyTime="0:0:2.5" Value="36"></span></div>
<div style="position:absolute;left:157.94px;top:567.00px" class="cls_007"><span class="cls_007"><EasingDoubleKeyFrame.EasingFunction></span></div>
<div style="position:absolute;left:172.93px;top:580.50px" class="cls_007"><span class="cls_007"><BackEase EasingMode="EaseOut" Amplitude="2" /></span></div>
<div style="position:absolute;left:157.94px;top:594.00px" class="cls_007"><span class="cls_007"></EasingDoubleKeyFrame.EasingFunction></span></div>
<div style="position:absolute;left:142.94px;top:607.50px" class="cls_007"><span class="cls_007"></EasingDoubleKeyFrame></span></div>
<div style="position:absolute;left:127.95px;top:621.00px" class="cls_007"><span class="cls_007"></DoubleAnimationUsingKeyFrames></span></div>
<div style="position:absolute;left:112.96px;top:634.50px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:97.96px;top:648.00px" class="cls_007"><span class="cls_007"></BeginStoryboard></span></div>
<div style="position:absolute;left:82.97px;top:661.50px" class="cls_007"><span class="cls_007"></EventTrigger></span></div>
<div style="position:absolute;left:67.97px;top:675.00px" class="cls_007"><span class="cls_007"></TextBlock.Triggers></span></div>
<div style="position:absolute;left:52.98px;top:688.50px" class="cls_007"><span class="cls_007"></TextBlock></span></div>
<div style="position:absolute;left:5.00px;top:708.75px" class="cls_004"><span class="cls_004">In this example, we animate the size of the text in a </span><span class="cls_007">TextBlock</span><span class="cls_004"> element using a number of</span></div>
<div style="position:absolute;left:5.00px;top:726.75px" class="cls_004"><span class="cls_004">key-frames. This creates the kind of transition effect that we might see on lines of text in</span></div>
<div style="position:absolute;left:5.00px;top:744.75px" class="cls_004"><span class="cls_004">Microsoft PowerPoint presentations and could be suitable to use in an application that</span></div>
<div style="position:absolute;left:5.00px;top:762.75px" class="cls_004"><span class="cls_004">presents textual information to the user.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:202104px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background254.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">We start by targeting the </span><span class="cls_007">FontSize</span><span class="cls_004"> property and specifying a total duration of two and a</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">half seconds. Our first key-frame simply sets our starting font size at zero seconds and so</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">we can use a </span><span class="cls_007">DiscreteDoubleKeyFrame</span><span class="cls_004"> for that. The second key-frame is an</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_007"><span class="cls_007">EasingDoubleKeyFrame</span><span class="cls_004"> element with a </span><span class="cls_007">BounceEase</span><span class="cls_004"> easing function and a duration, or key</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">time, of one second.</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">Following that, we have another </span><span class="cls_007">EasingDoubleKeyFrame</span><span class="cls_004"> element that lasts for one second,</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">but this one uses an </span><span class="cls_007">ElasticEase</span><span class="cls_004"> function. Finally, we finish with one further</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_007"><span class="cls_007">EasingDoubleKeyFrame</span><span class="cls_004"> element with a </span><span class="cls_007">BackEase</span><span class="cls_004"> easing function and a duration of half a</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">second. Note that we have used small values for the </span><span class="cls_007">Bounces</span><span class="cls_004"> and </span><span class="cls_007">Oscillations</span><span class="cls_004"> properties,</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">to keep the animation more usable.</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">Using these easing functions with key-frames enable us to chain any number of them</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">together to create more complicated animated effects. However, it is easy to go overboard</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">and create effects that are too much, as can be seen by increasing the values set for the</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_007"><span class="cls_007">Bounces</span><span class="cls_004"> and </span><span class="cls_007">Oscillations</span><span class="cls_004"> properties in this example. In reality, even the modest nvalues</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">used here could be considered to be too much for practical use.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:202906px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background255.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_008"><span class="cls_008">Animating along a path</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">There is one further method of animating property values in WPF. Using </span><span class="cls_007">PathFigure</span><span class="cls_004"> and</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_007"><span class="cls_007">PathSegment</span><span class="cls_004"> objects, we can construct a </span><span class="cls_007">PathGeometry</span><span class="cls_004"> object and then animate a property</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">value according to the </span><span class="cls_007">X</span><span class="cls_004">, </span><span class="cls_007">Y</span><span class="cls_004"> and/or rotation angle values of the path.</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">As this method is primarily used for animating objects along a complex path and therefore</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">not aimed at typical business applications, we will cover only the basics of this functionality</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">here. As with the other kinds of animation classes, there are different path animation types</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">that manipulate different CLR types. Path animation classes follow the naming convention</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_007"><span class="cls_007"><Type>AnimationUsingPath</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">Each </span><span class="cls_007"><Type>AnimationUsingPath</span><span class="cls_004"> class has a </span><span class="cls_007">PathGeometry</span><span class="cls_004"> property that we can use to</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">specify a path to animate along, using an object of type </span><span class="cls_007">PathGeometry</span><span class="cls_004">. In order to take</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">advantage of the ability to animate the path </span><span class="cls_007">X</span><span class="cls_004"> and </span><span class="cls_007">Y</span><span class="cls_004"> values in addition to the rotation angle,</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">we need to use a </span><span class="cls_007">MatrixTransform</span><span class="cls_004"> element. Let's see an example of this.</span></div>
<div style="position:absolute;left:52.98px;top:261.00px" class="cls_007"><span class="cls_007"><TextBlock Margin="100,125" Text="Hello World" FontSize="18"></span></div>
<div style="position:absolute;left:67.97px;top:274.50px" class="cls_007"><span class="cls_007"><TextBlock.RenderTransform></span></div>
<div style="position:absolute;left:82.97px;top:288.00px" class="cls_007"><span class="cls_007"><MatrixTransform x:Name="MatrixTransform"></span></div>
<div style="position:absolute;left:97.96px;top:301.50px" class="cls_007"><span class="cls_007"><MatrixTransform.Matrix></span></div>
<div style="position:absolute;left:112.96px;top:315.00px" class="cls_007"><span class="cls_007"><Matrix /></span></div>
<div style="position:absolute;left:97.96px;top:328.50px" class="cls_007"><span class="cls_007"></MatrixTransform.Matrix></span></div>
<div style="position:absolute;left:82.97px;top:342.00px" class="cls_007"><span class="cls_007"></MatrixTransform></span></div>
<div style="position:absolute;left:67.97px;top:355.50px" class="cls_007"><span class="cls_007"></TextBlock.RenderTransform></span></div>
<div style="position:absolute;left:67.97px;top:369.00px" class="cls_007"><span class="cls_007"><TextBlock.Triggers></span></div>
<div style="position:absolute;left:82.97px;top:382.50px" class="cls_007"><span class="cls_007"><EventTrigger RoutedEvent="TextBlock.Loaded"></span></div>
<div style="position:absolute;left:97.96px;top:396.00px" class="cls_007"><span class="cls_007"><BeginStoryboard></span></div>
<div style="position:absolute;left:112.96px;top:409.50px" class="cls_007"><span class="cls_007"><Storyboard></span></div>
<div style="position:absolute;left:127.95px;top:423.00px" class="cls_007"><span class="cls_007"><MatrixAnimationUsingPath</span></div>
<div style="position:absolute;left:142.94px;top:436.50px" class="cls_007"><span class="cls_007">Storyboard.TargetName="MatrixTransform"</span></div>
<div style="position:absolute;left:142.94px;top:450.00px" class="cls_007"><span class="cls_007">Storyboard.TargetProperty="Matrix" Duration="0:0:4"</span></div>
<div style="position:absolute;left:142.94px;top:463.50px" class="cls_007"><span class="cls_007">RepeatBehavior="Forever" DoesRotateWithTangent="True"></span></div>
<div style="position:absolute;left:142.94px;top:477.00px" class="cls_007"><span class="cls_007"><MatrixAnimationUsingPath.PathGeometry></span></div>
<div style="position:absolute;left:157.94px;top:490.50px" class="cls_007"><span class="cls_007"><PathGeometry></span></div>
<div style="position:absolute;left:172.93px;top:504.00px" class="cls_007"><span class="cls_007"><PathFigure StartPoint="49.99,49.99"></span></div>
<div style="position:absolute;left:187.92px;top:517.50px" class="cls_007"><span class="cls_007"><ArcSegment Point="50,50" Size="50,50"</span></div>
<div style="position:absolute;left:202.92px;top:531.00px" class="cls_007"><span class="cls_007">SweepDirection="Clockwise" IsLargeArc="True" /></span></div>
<div style="position:absolute;left:172.93px;top:544.50px" class="cls_007"><span class="cls_007"></PathFigure></span></div>
<div style="position:absolute;left:157.94px;top:558.00px" class="cls_007"><span class="cls_007"></PathGeometry></span></div>
<div style="position:absolute;left:142.94px;top:571.50px" class="cls_007"><span class="cls_007"></MatrixAnimationUsingPath.PathGeometry></span></div>
<div style="position:absolute;left:127.95px;top:585.00px" class="cls_007"><span class="cls_007"></MatrixAnimationUsingPath></span></div>
<div style="position:absolute;left:112.96px;top:598.50px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:97.96px;top:612.00px" class="cls_007"><span class="cls_007"></BeginStoryboard></span></div>
<div style="position:absolute;left:82.97px;top:625.50px" class="cls_007"><span class="cls_007"></EventTrigger></span></div>
<div style="position:absolute;left:67.97px;top:639.00px" class="cls_007"><span class="cls_007"></TextBlock.Triggers></span></div>
<div style="position:absolute;left:52.98px;top:652.50px" class="cls_007"><span class="cls_007"></TextBlock></span></div>
<div style="position:absolute;left:5.00px;top:685.50px" class="cls_004"><span class="cls_004">In this example, we animate a </span><span class="cls_007">TextBlock</span><span class="cls_004"> element around a circular path using a</span></div>
<div style="position:absolute;left:5.00px;top:703.50px" class="cls_007"><span class="cls_007">MatrixAnimationUsingPath</span><span class="cls_004"> element. The circular path is defined by a single </span><span class="cls_007">ArcSegment</span></div>
<div style="position:absolute;left:5.00px;top:721.50px" class="cls_004"><span class="cls_004">element within a single </span><span class="cls_007">PathFigure</span><span class="cls_004"> element. We set the </span><span class="cls_007">PathFigure.StartPoint</span><span class="cls_004"> property</span></div>
<div style="position:absolute;left:5.00px;top:739.50px" class="cls_004"><span class="cls_004">value to almost match the </span><span class="cls_007">ArcSegment.Point</span><span class="cls_004"> value so that the two ends of the ellipse meet.</span></div>
<div style="position:absolute;left:5.00px;top:757.50px" class="cls_004"><span class="cls_004">In order to animate the rotation of the text element from the </span><span class="cls_007">MatrixAnimationUsingPath</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:203708px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background256.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">element, we need to set its </span><span class="cls_007">DoesRotateWithTangent</span><span class="cls_004"> property to </span><span class="cls_007">true</span><span class="cls_004">. If this property was</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">set to </span><span class="cls_007">false</span><span class="cls_004">, or simply omitted, then the text element would still be animated in a circular</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">motion, but it would no longer rotate in line with the tangent of the circular path, instead</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">remaining upright.</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">In addition to the </span><span class="cls_007">MatrixAnimationUsingPath</span><span class="cls_004"> class, we can also use either of the</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_007"><span class="cls_007">DoubleAnimationUsingPath</span><span class="cls_004"> or </span><span class="cls_007">PointAnimationUsingPath</span><span class="cls_004"> classes to animate objects on a</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">path. However, rather than providing examples for these alternative methods, let's now</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">move on to find out how we can include every day animations in our application framework.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:204510px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background257.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_008"><span class="cls_008">Creating everyday animations</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">After covering the wide range of animations that WPF provides, we can see that many of</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">them were designed to enable us to perform animations that emulate real-world situations,</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">rather than to animate form fields in a standard business application. As such, some of the</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">techniques discussed in this chapter are inappropriate for use in our application framework.</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">However, this does not mean that we cannot create animations to use in our everyday</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">applications. As long as we remember that less is more when it comes to animations in</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">business applications, we can certainly build simple animations into our application</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">framework. One of the best ways to encapsulate these basic animations in our framework</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">is to write one or more custom-animated panels. Let's look at a simple example of an</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">animated </span><span class="cls_007">StackPanel</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:52.98px;top:225.00px" class="cls_007"><span class="cls_007">using System;</span></div>
<div style="position:absolute;left:52.98px;top:238.50px" class="cls_007"><span class="cls_007">using System.Windows;</span></div>
<div style="position:absolute;left:52.98px;top:252.00px" class="cls_007"><span class="cls_007">using System.Windows.Controls;</span></div>
<div style="position:absolute;left:52.98px;top:265.50px" class="cls_007"><span class="cls_007">using System.Windows.Media;</span></div>
<div style="position:absolute;left:52.98px;top:279.00px" class="cls_007"><span class="cls_007">using System.Windows.Media.Animation;</span></div>
<div style="position:absolute;left:52.98px;top:306.00px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.Views.Panels</span></div>
<div style="position:absolute;left:52.98px;top:319.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:333.00px" class="cls_007"><span class="cls_007">public class AnimatedStackPanel : Panel</span></div>
<div style="position:absolute;left:67.97px;top:346.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:360.00px" class="cls_007"><span class="cls_007">public static DependencyProperty OrientationProperty =</span></div>
<div style="position:absolute;left:97.96px;top:373.50px" class="cls_007"><span class="cls_007">DependencyProperty.Register(nameof(Orientation),</span></div>
<div style="position:absolute;left:97.96px;top:387.00px" class="cls_007"><span class="cls_007">typeof(Orientation), typeof(AnimatedStackPanel),</span></div>
<div style="position:absolute;left:97.96px;top:400.50px" class="cls_007"><span class="cls_007">new PropertyMetadata(Orientation.Vertical));</span></div>
<div style="position:absolute;left:82.97px;top:427.50px" class="cls_007"><span class="cls_007">public Orientation Orientation</span></div>
<div style="position:absolute;left:82.97px;top:441.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:454.50px" class="cls_007"><span class="cls_007">get { return (Orientation)GetValue(OrientationProperty); }</span></div>
<div style="position:absolute;left:97.96px;top:468.00px" class="cls_007"><span class="cls_007">set { SetValue(OrientationProperty, value); }</span></div>
<div style="position:absolute;left:82.97px;top:481.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:508.50px" class="cls_007"><span class="cls_007">protected override Size MeasureOverride(Size availableSize)</span></div>
<div style="position:absolute;left:82.97px;top:522.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:535.50px" class="cls_007"><span class="cls_007">double x = 0, y = 0;</span></div>
<div style="position:absolute;left:97.96px;top:549.00px" class="cls_007"><span class="cls_007">foreach (UIElement child in Children)</span></div>
<div style="position:absolute;left:97.96px;top:562.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:112.96px;top:576.00px" class="cls_007"><span class="cls_007">child.Measure(availableSize);</span></div>
<div style="position:absolute;left:112.96px;top:589.50px" class="cls_007"><span class="cls_007">if (Orientation == Orientation.Horizontal)</span></div>
<div style="position:absolute;left:112.96px;top:603.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:127.95px;top:616.50px" class="cls_007"><span class="cls_007">x += child.DesiredSize.Width;</span></div>
<div style="position:absolute;left:127.95px;top:630.00px" class="cls_007"><span class="cls_007">y = Math.Max(y, child.DesiredSize.Height);</span></div>
<div style="position:absolute;left:112.96px;top:643.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:112.96px;top:657.00px" class="cls_007"><span class="cls_007">else</span></div>
<div style="position:absolute;left:112.96px;top:670.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:127.95px;top:684.00px" class="cls_007"><span class="cls_007">x = Math.Max(x, child.DesiredSize.Width);</span></div>
<div style="position:absolute;left:127.95px;top:697.50px" class="cls_007"><span class="cls_007">y += child.DesiredSize.Height;</span></div>
<div style="position:absolute;left:112.96px;top:711.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:97.96px;top:724.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:97.96px;top:738.00px" class="cls_007"><span class="cls_007">return new Size(x, y);</span></div>
<div style="position:absolute;left:82.97px;top:751.50px" class="cls_007"><span class="cls_007">}</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:205312px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background258.jpg" width=612 height=792></div>
<div style="position:absolute;left:82.97px;top:3.00px" class="cls_007"><span class="cls_007">protected override Size ArrangeOverride(Size finalSize)</span></div>
<div style="position:absolute;left:82.97px;top:16.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:30.00px" class="cls_007"><span class="cls_007">Point endPosition = new Point();</span></div>
<div style="position:absolute;left:97.96px;top:43.50px" class="cls_007"><span class="cls_007">foreach (UIElement child in Children)</span></div>
<div style="position:absolute;left:97.96px;top:57.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:112.96px;top:70.50px" class="cls_007"><span class="cls_007">child.Arrange(Orientation == Orientation.Horizontal ?</span></div>
<div style="position:absolute;left:127.95px;top:84.00px" class="cls_007"><span class="cls_007">new Rect(child.DesiredSize) :</span></div>
<div style="position:absolute;left:127.95px;top:97.50px" class="cls_007"><span class="cls_007">new Rect(0, 0, finalSize.Width,</span></div>
<div style="position:absolute;left:52.98px;top:111.00px" class="cls_007"><span class="cls_007">child.DesiredSize.Height));</span></div>
<div style="position:absolute;left:112.96px;top:124.50px" class="cls_007"><span class="cls_007">AnimatePosition(child, endPosition,</span></div>
<div style="position:absolute;left:127.95px;top:138.00px" class="cls_007"><span class="cls_007">TimeSpan.FromMilliseconds(300));</span></div>
<div style="position:absolute;left:112.96px;top:151.50px" class="cls_007"><span class="cls_007">if (Orientation == Orientation.Horizontal)</span></div>
<div style="position:absolute;left:127.95px;top:165.00px" class="cls_007"><span class="cls_007">endPosition.X += child.DesiredSize.Width;</span></div>
<div style="position:absolute;left:112.96px;top:178.50px" class="cls_007"><span class="cls_007">else endPosition.Y += child.DesiredSize.Height;</span></div>
<div style="position:absolute;left:97.96px;top:192.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:97.96px;top:205.50px" class="cls_007"><span class="cls_007">return finalSize;</span></div>
<div style="position:absolute;left:82.97px;top:219.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:246.00px" class="cls_007"><span class="cls_007">private void AnimatePosition(UIElement child, Point</span></div>
<div style="position:absolute;left:52.98px;top:259.50px" class="cls_007"><span class="cls_007">endPosition,</span></div>
<div style="position:absolute;left:97.96px;top:273.00px" class="cls_007"><span class="cls_007">TimeSpan animationDuration)</span></div>
<div style="position:absolute;left:82.97px;top:286.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:300.00px" class="cls_007"><span class="cls_007">if (Orientation == Orientation. Vertical)</span></div>
<div style="position:absolute;left:112.96px;top:313.50px" class="cls_007"><span class="cls_007">GetTranslateTransform(child).BeginAnimation(</span></div>
<div style="position:absolute;left:112.96px;top:327.00px" class="cls_007"><span class="cls_007">TranslateTransform.YProperty,</span></div>
<div style="position:absolute;left:112.96px;top:340.50px" class="cls_007"><span class="cls_007">new DoubleAnimation(endPosition.Y, animationDuration));</span></div>
<div style="position:absolute;left:97.96px;top:354.00px" class="cls_007"><span class="cls_007">else GetTranslateTransform(child).BeginAnimation(</span></div>
<div style="position:absolute;left:112.96px;top:367.50px" class="cls_007"><span class="cls_007">TranslateTransform.XProperty,</span></div>
<div style="position:absolute;left:112.96px;top:381.00px" class="cls_007"><span class="cls_007">new DoubleAnimation(endPosition.X, animationDuration));</span></div>
<div style="position:absolute;left:82.97px;top:394.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:421.50px" class="cls_007"><span class="cls_007">private TranslateTransform GetTranslateTransform(UIElement</span></div>
<div style="position:absolute;left:52.98px;top:435.00px" class="cls_007"><span class="cls_007">child)</span></div>
<div style="position:absolute;left:82.97px;top:448.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:462.00px" class="cls_007"><span class="cls_007">return child.RenderTransform as TranslateTransform ??</span></div>
<div style="position:absolute;left:112.96px;top:475.50px" class="cls_007"><span class="cls_007">AddTranslateTransform(child);</span></div>
<div style="position:absolute;left:82.97px;top:489.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:516.00px" class="cls_007"><span class="cls_007">private TranslateTransform AddTranslateTransform(UIElement</span></div>
<div style="position:absolute;left:52.98px;top:529.50px" class="cls_007"><span class="cls_007">child)</span></div>
<div style="position:absolute;left:82.97px;top:543.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:556.50px" class="cls_007"><span class="cls_007">TranslateTransform translateTransform = new</span></div>
<div style="position:absolute;left:52.98px;top:570.00px" class="cls_007"><span class="cls_007">TranslateTransform();</span></div>
<div style="position:absolute;left:97.96px;top:583.50px" class="cls_007"><span class="cls_007">child.RenderTransform = translateTransform;</span></div>
<div style="position:absolute;left:97.96px;top:597.00px" class="cls_007"><span class="cls_007">return translateTransform;</span></div>
<div style="position:absolute;left:82.97px;top:610.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:624.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:637.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:657.75px" class="cls_004"><span class="cls_004">As with all custom panels, we just need to provide the implementation for the</span></div>
<div style="position:absolute;left:5.00px;top:675.75px" class="cls_007"><span class="cls_007">MeasureOverride</span><span class="cls_004"> and </span><span class="cls_007">ArrangeOverride</span><span class="cls_004"> methods. However, in our case, we want to</span></div>
<div style="position:absolute;left:5.00px;top:693.75px" class="cls_004"><span class="cls_004">recreate the functionality of the original </span><span class="cls_007">StackPanel</span><span class="cls_004"> control and so we have also declared</span></div>
<div style="position:absolute;left:5.00px;top:711.75px" class="cls_004"><span class="cls_004">an </span><span class="cls_007">Orientation</span><span class="cls_004"> Dependency Property of type </span><span class="cls_007">System.Windows.Controls.Orientation</span><span class="cls_004">,</span></div>
<div style="position:absolute;left:5.00px;top:729.75px" class="cls_004"><span class="cls_004">with a default value of </span><span class="cls_007">Vertical</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:747.75px" class="cls_004"><span class="cls_004">In the </span><span class="cls_007">MeasureOverride</span><span class="cls_004"> method, we iterate through each of the panel's children, calling their</span></div>
<div style="position:absolute;left:5.00px;top:765.75px" class="cls_007"><span class="cls_007">Measure</span><span class="cls_004"> method, passing in the </span><span class="cls_007">availableSize</span><span class="cls_004"> input parameter. Note that this sets their</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:206114px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background259.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_007"><span class="cls_007">DesiredSize</span><span class="cls_004"> property, which will be set to a size of </span><span class="cls_007">0</span><span class="cls_004">, </span><span class="cls_007">0</span><span class="cls_004"> until this point.</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">After calling the </span><span class="cls_007">Measure</span><span class="cls_004"> method on each child, we are able to use their </span><span class="cls_007">DesiredSize</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">property values to calculate the total size required to properly display the rendered items,</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">depending on the value of the </span><span class="cls_007">Orientation</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">If the </span><span class="cls_007">Orientation</span><span class="cls_004"> property is set to </span><span class="cls_007">Vertical</span><span class="cls_004">, we use the </span><span class="cls_007">Math.Max</span><span class="cls_004"> method to ensure that</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">we keep account of the size of the widest element and if it is set to </span><span class="cls_007">Horizontal</span><span class="cls_004">, then we</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">use it to find height of the tallest element. Once each child has been measured and the</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">overall required size of the panel has been calculated, we return this size value from the</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_007"><span class="cls_007">MeasureOverride</span><span class="cls_004"> method.</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">In the </span><span class="cls_007">ArrangeOverride</span><span class="cls_004"> method, we again iterate through the collection of children, but this</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">time we call the </span><span class="cls_007">Arrange</span><span class="cls_004"> method on each child, positioning them at the origin point of </span><span class="cls_007">0</span><span class="cls_004">, </span><span class="cls_007">0</span><span class="cls_004">,</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">which will be the starting point of their animations. We pass the size of the child into this</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">method if the </span><span class="cls_007">Orientation</span><span class="cls_004"> property is set to </span><span class="cls_007">Vertical</span><span class="cls_004">, but use the width value of the</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_007"><span class="cls_007">finalSize</span><span class="cls_004"> input parameter as the child's width if it is set to </span><span class="cls_007">Horizontal</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">This has the effect of stretching each item across the width of the panel when the vertical</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">option is being used, as neatly aligned items with uniform widths look more tidy and</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">professional than items with uneven edges. In this way, we can build these kinds of</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">decisions right into our framework controls.</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_004"><span class="cls_004">Next, we call the </span><span class="cls_007">AnimatePosition</span><span class="cls_004"> method, passing in the child, the desired end position of</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_004"><span class="cls_004">the child after animation and the duration of the animation. We then calculate the desired</span></div>
<div style="position:absolute;left:5.00px;top:363.75px" class="cls_004"><span class="cls_004">end position of the next child with the </span><span class="cls_007">endPosition</span><span class="cls_004"> variable, again taking the value of the</span></div>
<div style="position:absolute;left:5.00px;top:381.75px" class="cls_007"><span class="cls_007">Orientation</span><span class="cls_004"> property into consideration. We end the method by returning the unchanged</span></div>
<div style="position:absolute;left:5.00px;top:399.75px" class="cls_007"><span class="cls_007">finalSize</span><span class="cls_004"> input parameter.</span></div>
<div style="position:absolute;left:5.00px;top:417.75px" class="cls_004"><span class="cls_004">In the </span><span class="cls_007">AnimatePosition</span><span class="cls_004"> method, we call the </span><span class="cls_007">GetTranslateTransform</span><span class="cls_004"> method to get the</span></div>
<div style="position:absolute;left:5.00px;top:435.75px" class="cls_007"><span class="cls_007">TranslateTransform</span><span class="cls_004"> object that we will use to move each child across the panel. If the</span></div>
<div style="position:absolute;left:5.00px;top:453.75px" class="cls_007"><span class="cls_007">Orientation</span><span class="cls_004"> property is set to </span><span class="cls_007">Vertical</span><span class="cls_004">, we animate the </span><span class="cls_007">TranslateTransform.YProperty</span></div>
<div style="position:absolute;left:5.00px;top:471.75px" class="cls_004"><span class="cls_004">property to the value of the </span><span class="cls_007">endPosition.Y</span><span class="cls_004"> property, otherwise we animate the</span></div>
<div style="position:absolute;left:5.00px;top:489.75px" class="cls_007"><span class="cls_007">TranslateTransform.XProperty</span><span class="cls_004"> property to the value of the </span><span class="cls_007">endPosition.X</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:5.00px;top:507.75px" class="cls_004"><span class="cls_004">In order to animate these property values, we use the </span><span class="cls_007">BeginAnimation</span><span class="cls_004"> method on the</span></div>
<div style="position:absolute;left:5.00px;top:525.75px" class="cls_007"><span class="cls_007">UIElement</span><span class="cls_004"> object with the property to be added. There are two overloads of this method,</span></div>
<div style="position:absolute;left:5.00px;top:543.75px" class="cls_004"><span class="cls_004">but we are using one that accepts the key of the Dependency Property to animate and the</span></div>
<div style="position:absolute;left:5.00px;top:561.75px" class="cls_004"><span class="cls_004">animation object. The other overload enables us to specify the </span><span class="cls_007">HandoffBehavior</span><span class="cls_004"> to use with</span></div>
<div style="position:absolute;left:5.00px;top:579.75px" class="cls_004"><span class="cls_004">the animation.</span></div>
<div style="position:absolute;left:5.00px;top:597.75px" class="cls_004"><span class="cls_004">For our animation, we are using a </span><span class="cls_007">DoubleAnimation</span><span class="cls_004">, with a constructor that accepts the </span><span class="cls_007">To</span></div>
<div style="position:absolute;left:5.00px;top:615.75px" class="cls_004"><span class="cls_004">value and the duration of the animation, although there are several other overloads that we</span></div>
<div style="position:absolute;left:5.00px;top:633.75px" class="cls_004"><span class="cls_004">could have used, had we needed to specify further properties, such as the </span><span class="cls_007">From</span><span class="cls_004"> and</span></div>
<div style="position:absolute;left:5.00px;top:651.75px" class="cls_007"><span class="cls_007">FillBehavior</span><span class="cls_004"> values.</span></div>
<div style="position:absolute;left:5.00px;top:669.75px" class="cls_004"><span class="cls_004">In order to animate the movement of the items in the panel, we need to ensure that they</span></div>
<div style="position:absolute;left:5.00px;top:687.75px" class="cls_004"><span class="cls_004">have a </span><span class="cls_007">TranslateTransform</span><span class="cls_004"> element applied to the </span><span class="cls_007">RenderTransform</span><span class="cls_004"> property of the</span></div>
<div style="position:absolute;left:5.00px;top:705.75px" class="cls_004"><span class="cls_004">container item of each child. Remember that different </span><span class="cls_007">ItemsControl</span><span class="cls_004"> classes will use</span></div>
<div style="position:absolute;left:5.00px;top:723.75px" class="cls_004"><span class="cls_004">different container items, for example, a </span><span class="cls_007">ListBox</span><span class="cls_004"> control will use </span><span class="cls_007">ListBoxItem</span><span class="cls_004"> container</span></div>
<div style="position:absolute;left:5.00px;top:741.75px" class="cls_004"><span class="cls_004">elements.</span></div>
<div style="position:absolute;left:5.00px;top:759.75px" class="cls_004"><span class="cls_004">Therefore, if an item does not already have a </span><span class="cls_007">TranslateTransform</span><span class="cls_004"> element applied, we</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:206916px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background260.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">must add one. Once each element has a </span><span class="cls_007">TranslateTransform</span><span class="cls_004"> element, we can use its </span><span class="cls_007">X</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">and </span><span class="cls_007">Y</span><span class="cls_004"> properties to move the item.</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">In the </span><span class="cls_007">GetTranslateTransform</span><span class="cls_004"> method, we simply return the existing </span><span class="cls_007">TranslateTransform</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">element from the </span><span class="cls_007">RenderTransform</span><span class="cls_004"> property of each child if one exists, or call the</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_007"><span class="cls_007">AddTranslateTransform</span><span class="cls_004"> method to return a new one otherwise. In the</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_007"><span class="cls_007">AddTranslateTransform</span><span class="cls_004"> method, we just initialize a new </span><span class="cls_007">TranslateTransform</span><span class="cls_004"> element and</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">set it to the </span><span class="cls_007">RenderTransform</span><span class="cls_004"> property of the </span><span class="cls_007">child</span><span class="cls_004"> input parameter, before returning it.</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">We've now created a basic animated panel and with just around seventy lines of code. The</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">developers that use our application framework can now animate the entry of items in any</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_007"><span class="cls_007">ItemsControl</span><span class="cls_004">, or any of its derived collection controls, by simply specifying it in a</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_007"><span class="cls_007">ItemsPanelTemplate</span><span class="cls_004"> as the </span><span class="cls_007">ItemsPanel</span><span class="cls_004"> value.</span></div>
<div style="position:absolute;left:52.98px;top:207.00px" class="cls_007"><span class="cls_007">xmlns:Panels="clr-</span></div>
<div style="position:absolute;left:52.98px;top:220.50px" class="cls_007"><span class="cls_007">namespace:CompanyName.ApplicationName.Views.Panels"</span></div>
<div style="position:absolute;left:52.98px;top:247.50px" class="cls_007"><span class="cls_007"><ListBox ItemsSource="{Binding Users}"></span></div>
<div style="position:absolute;left:67.97px;top:261.00px" class="cls_007"><span class="cls_007"><ListBox.ItemsPanel></span></div>
<div style="position:absolute;left:82.97px;top:274.50px" class="cls_007"><span class="cls_007"><ItemsPanelTemplate></span></div>
<div style="position:absolute;left:97.96px;top:288.00px" class="cls_007"><span class="cls_007"><Panels:AnimatedStackPanel /></span></div>
<div style="position:absolute;left:82.97px;top:301.50px" class="cls_007"><span class="cls_007"></ItemsPanelTemplate></span></div>
<div style="position:absolute;left:67.97px;top:315.00px" class="cls_007"><span class="cls_007"></ListBox.ItemsPanel></span></div>
<div style="position:absolute;left:52.98px;top:328.50px" class="cls_007"><span class="cls_007"></ListBox></span></div>
<div style="position:absolute;left:5.00px;top:348.75px" class="cls_004"><span class="cls_004">However, our panel currently only provides one type of animation, albeit in two possible</span></div>
<div style="position:absolute;left:5.00px;top:366.75px" class="cls_004"><span class="cls_004">directions, and only works as new items are added. Animating objects' exit is somewhat</span></div>
<div style="position:absolute;left:5.00px;top:384.75px" class="cls_004"><span class="cls_004">trickier, because they are normally removed immediately from the panel's </span><span class="cls_007">Children</span></div>
<div style="position:absolute;left:5.00px;top:402.75px" class="cls_004"><span class="cls_004">collection when the </span><span class="cls_007">Remove</span><span class="cls_004"> method is called on the data bound collection.</span></div>
<div style="position:absolute;left:5.00px;top:420.75px" class="cls_004"><span class="cls_004">In order to accomplish working exit animations, we'll need to implement a number of things.</span></div>
<div style="position:absolute;left:5.00px;top:438.75px" class="cls_004"><span class="cls_004">We'll need to update our data model classes to provide them with new properties to identify</span></div>
<div style="position:absolute;left:5.00px;top:456.75px" class="cls_004"><span class="cls_004">which stage of the animation that they're currently in and new events to raise when the</span></div>
<div style="position:absolute;left:5.00px;top:474.75px" class="cls_004"><span class="cls_004">current status changes.</span></div>
<div style="position:absolute;left:5.00px;top:492.75px" class="cls_004"><span class="cls_004">We'll need an </span><span class="cls_007">IAnimatable</span><span class="cls_004"> interface and an </span><span class="cls_007">Animatable</span><span class="cls_004"> class that provides the</span></div>
<div style="position:absolute;left:5.00px;top:510.75px" class="cls_004"><span class="cls_004">implementation for each data model. Let's first see the interface.</span></div>
<div style="position:absolute;left:52.98px;top:534.00px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.DataModels.Interfaces</span></div>
<div style="position:absolute;left:52.98px;top:547.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:561.00px" class="cls_007"><span class="cls_007">public interface IAnimatable</span></div>
<div style="position:absolute;left:67.97px;top:574.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:588.00px" class="cls_007"><span class="cls_007">Animatable Animatable { get; set; }</span></div>
<div style="position:absolute;left:67.97px;top:601.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:615.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:635.25px" class="cls_004"><span class="cls_004">Now let's see the implementation of the </span><span class="cls_007">Animatable</span><span class="cls_004"> class:</span></div>
<div style="position:absolute;left:52.98px;top:658.50px" class="cls_007"><span class="cls_007">using System;</span></div>
<div style="position:absolute;left:52.98px;top:672.00px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.DataModels.Enums;</span></div>
<div style="position:absolute;left:52.98px;top:685.50px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.DataModels.Interfaces;</span></div>
<div style="position:absolute;left:52.98px;top:712.50px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.DataModels</span></div>
<div style="position:absolute;left:52.98px;top:726.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:739.50px" class="cls_007"><span class="cls_007">public class Animatable</span></div>
<div style="position:absolute;left:67.97px;top:753.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:766.50px" class="cls_007"><span class="cls_007">private AdditionStatus additionStatus =</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:207718px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background261.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:3.00px" class="cls_007"><span class="cls_007">AdditionStatus.ReadyToAnimate;</span></div>
<div style="position:absolute;left:82.97px;top:16.50px" class="cls_007"><span class="cls_007">private RemovalStatus removalStatus = RemovalStatus.None;</span></div>
<div style="position:absolute;left:82.97px;top:30.00px" class="cls_007"><span class="cls_007">private TransitionStatus transitionStatus =</span></div>
<div style="position:absolute;left:52.98px;top:43.50px" class="cls_007"><span class="cls_007">TransitionStatus.None;</span></div>
<div style="position:absolute;left:82.97px;top:57.00px" class="cls_007"><span class="cls_007">private IAnimatable owner;</span></div>
<div style="position:absolute;left:82.97px;top:84.00px" class="cls_007"><span class="cls_007">public Animatable(IAnimatable owner)</span></div>
<div style="position:absolute;left:82.97px;top:97.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:111.00px" class="cls_007"><span class="cls_007">Owner = owner;</span></div>
<div style="position:absolute;left:82.97px;top:124.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:151.50px" class="cls_007"><span class="cls_007">public Animatable() { }</span></div>
<div style="position:absolute;left:82.97px;top:178.50px" class="cls_007"><span class="cls_007">public event EventHandler<EventArgs> OnRemovalStatusChanged;</span></div>
<div style="position:absolute;left:82.97px;top:192.00px" class="cls_007"><span class="cls_007">public event EventHandler<EventArgs> OnTransitionStatusChanged;</span></div>
<div style="position:absolute;left:82.97px;top:219.00px" class="cls_007"><span class="cls_007">public IAnimatable Owner</span></div>
<div style="position:absolute;left:82.97px;top:232.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:246.00px" class="cls_007"><span class="cls_007">get { return owner; }</span></div>
<div style="position:absolute;left:97.96px;top:259.50px" class="cls_007"><span class="cls_007">set { owner = value; }</span></div>
<div style="position:absolute;left:82.97px;top:273.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:300.00px" class="cls_007"><span class="cls_007">public AdditionStatus AdditionStatus</span></div>
<div style="position:absolute;left:82.97px;top:313.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:327.00px" class="cls_007"><span class="cls_007">get { return additionStatus; }</span></div>
<div style="position:absolute;left:97.96px;top:340.50px" class="cls_007"><span class="cls_007">set { additionStatus = value; }</span></div>
<div style="position:absolute;left:82.97px;top:354.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:381.00px" class="cls_007"><span class="cls_007">public TransitionStatus TransitionStatus</span></div>
<div style="position:absolute;left:82.97px;top:394.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:408.00px" class="cls_007"><span class="cls_007">get { return transitionStatus; }</span></div>
<div style="position:absolute;left:97.96px;top:421.50px" class="cls_007"><span class="cls_007">set</span></div>
<div style="position:absolute;left:97.96px;top:435.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:112.96px;top:448.50px" class="cls_007"><span class="cls_007">transitionStatus = value;</span></div>
<div style="position:absolute;left:112.96px;top:462.00px" class="cls_007"><span class="cls_007">OnTransitionStatusChanged?.Invoke(this, new EventArgs());</span></div>
<div style="position:absolute;left:97.96px;top:475.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:489.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:516.00px" class="cls_007"><span class="cls_007">public RemovalStatus RemovalStatus</span></div>
<div style="position:absolute;left:82.97px;top:529.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:543.00px" class="cls_007"><span class="cls_007">get { return removalStatus; }</span></div>
<div style="position:absolute;left:97.96px;top:556.50px" class="cls_007"><span class="cls_007">set</span></div>
<div style="position:absolute;left:97.96px;top:570.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:112.96px;top:583.50px" class="cls_007"><span class="cls_007">removalStatus = value;</span></div>
<div style="position:absolute;left:112.96px;top:597.00px" class="cls_007"><span class="cls_007">OnRemovalStatusChanged?.Invoke(this, new EventArgs());</span></div>
<div style="position:absolute;left:97.96px;top:610.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:624.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:637.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:651.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:684.00px" class="cls_004"><span class="cls_004">This class needs little explanation, other than to note that the </span><span class="cls_007">On</span><span class="cls_004"> </span><span class="cls_007">TransitionStatusChanged</span></div>
<div style="position:absolute;left:5.00px;top:702.00px" class="cls_004"><span class="cls_004">and </span><span class="cls_007">OnRemovalStatusChanged</span><span class="cls_004"> events get raised when the values of the </span><span class="cls_007">TransitionStatus</span></div>
<div style="position:absolute;left:5.00px;top:720.00px" class="cls_004"><span class="cls_004">and </span><span class="cls_007">RemovalStatus</span><span class="cls_004"> properties are changed respectively and that the class passes itself in</span></div>
<div style="position:absolute;left:5.00px;top:738.00px" class="cls_004"><span class="cls_004">as the </span><span class="cls_007">sender</span><span class="cls_004"> input parameter in each case. Let's see the three new enumeration classes</span></div>
<div style="position:absolute;left:5.00px;top:756.00px" class="cls_004"><span class="cls_004">that are used in our </span><span class="cls_007">Animatable</span><span class="cls_004"> class.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:208520px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background262.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:9.00px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.DataModels.Enums</span></div>
<div style="position:absolute;left:52.98px;top:22.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:36.00px" class="cls_007"><span class="cls_007">public enum AdditionStatus</span></div>
<div style="position:absolute;left:67.97px;top:49.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:63.00px" class="cls_007"><span class="cls_007">None = -1, ReadyToAnimate = 0, DoNotAnimate = 1, Added = 2</span></div>
<div style="position:absolute;left:67.97px;top:76.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:103.50px" class="cls_007"><span class="cls_007">public enum TransitionStatus</span></div>
<div style="position:absolute;left:67.97px;top:117.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:130.50px" class="cls_007"><span class="cls_007">None = -1, ReadyToAnimate = 0, AnimationComplete = 1</span></div>
<div style="position:absolute;left:67.97px;top:144.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:171.00px" class="cls_007"><span class="cls_007">public enum RemovalStatus</span></div>
<div style="position:absolute;left:67.97px;top:184.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:198.00px" class="cls_007"><span class="cls_007">None = -1, ReadyToAnimate = 0, ReadyToRemove = 1</span></div>
<div style="position:absolute;left:67.97px;top:211.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:225.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:245.25px" class="cls_004"><span class="cls_004">We then need to implement this interface in each data model class that we want to</span></div>
<div style="position:absolute;left:5.00px;top:263.25px" class="cls_004"><span class="cls_004">animate.</span></div>
<div style="position:absolute;left:52.98px;top:286.50px" class="cls_007"><span class="cls_007">public class User : ... , IAnimatable</span></div>
<div style="position:absolute;left:52.98px;top:300.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:313.50px" class="cls_007"><span class="cls_007">private Animatable animatable;</span></div>
<div style="position:absolute;left:67.97px;top:367.50px" class="cls_007"><span class="cls_007">public User(Guid id, string name, int age)</span></div>
<div style="position:absolute;left:67.97px;top:381.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:394.50px" class="cls_007"><span class="cls_007">Animatable = new Animatable(this);</span></div>
<div style="position:absolute;left:67.97px;top:421.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:448.50px" class="cls_007"><span class="cls_007">public Animatable Animatable</span></div>
<div style="position:absolute;left:67.97px;top:462.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:475.50px" class="cls_007"><span class="cls_007">get { return animatable; }</span></div>
<div style="position:absolute;left:82.97px;top:489.00px" class="cls_007"><span class="cls_007">set { animatable = value; }</span></div>
<div style="position:absolute;left:67.97px;top:502.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:543.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:563.25px" class="cls_004"><span class="cls_004">The next thing that we need to do, is to stop the </span><span class="cls_007">Remove</span><span class="cls_004"> method from actually removing</span></div>
<div style="position:absolute;left:5.00px;top:581.25px" class="cls_004"><span class="cls_004">each item when called. We'll need to update our </span><span class="cls_007">BaseCollection<T></span><span class="cls_004"> class, or add a new</span></div>
<div style="position:absolute;left:5.00px;top:599.25px" class="cls_007"><span class="cls_007">BaseAnimatableCollection<T></span><span class="cls_004"> class, so that it triggers the animation instead of removing</span></div>
<div style="position:absolute;left:5.00px;top:617.25px" class="cls_004"><span class="cls_004">the item directly. Here is a cut down example showing one way that we might do this.</span></div>
<div style="position:absolute;left:52.98px;top:640.50px" class="cls_007"><span class="cls_007">using System;</span></div>
<div style="position:absolute;left:52.98px;top:654.00px" class="cls_007"><span class="cls_007">using System.Collections.Generic;</span></div>
<div style="position:absolute;left:52.98px;top:667.50px" class="cls_007"><span class="cls_007">using System.ComponentModel;</span></div>
<div style="position:absolute;left:52.98px;top:681.00px" class="cls_007"><span class="cls_007">using System.Linq;</span></div>
<div style="position:absolute;left:52.98px;top:694.50px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.DataModels.Enums;</span></div>
<div style="position:absolute;left:52.98px;top:708.00px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.DataModels.Interfaces;</span></div>
<div style="position:absolute;left:52.98px;top:735.00px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.DataModels.Collections</span></div>
<div style="position:absolute;left:52.98px;top:748.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:762.00px" class="cls_007"><span class="cls_007">public class BaseAnimatableCollection<T> : BaseCollection<T></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:209322px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background263.jpg" width=612 height=792></div>
<div style="position:absolute;left:82.97px;top:3.00px" class="cls_007"><span class="cls_007">where T : class, IAnimatable, INotifyPropertyChanged, new()</span></div>
<div style="position:absolute;left:67.97px;top:16.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:30.00px" class="cls_007"><span class="cls_007">private bool isAnimatable = true;</span></div>
<div style="position:absolute;left:82.97px;top:57.00px" class="cls_007"><span class="cls_007">public BaseAnimatableCollection(IEnumerable<T> collection)</span></div>
<div style="position:absolute;left:82.97px;top:70.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:84.00px" class="cls_007"><span class="cls_007">foreach (T item in collection) Add(item);</span></div>
<div style="position:absolute;left:82.97px;top:97.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:151.50px" class="cls_007"><span class="cls_007">public bool IsAnimatable</span></div>
<div style="position:absolute;left:82.97px;top:165.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:178.50px" class="cls_007"><span class="cls_007">get { return isAnimatable; }</span></div>
<div style="position:absolute;left:97.96px;top:192.00px" class="cls_007"><span class="cls_007">set { isAnimatable = value; }</span></div>
<div style="position:absolute;left:82.97px;top:205.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:232.50px" class="cls_007"><span class="cls_007">public new int Count => IsAnimatable ?</span></div>
<div style="position:absolute;left:97.96px;top:246.00px" class="cls_007"><span class="cls_007">this.Count(i => i.Animatable.RemovalStatus ==</span></div>
<div style="position:absolute;left:52.98px;top:259.50px" class="cls_007"><span class="cls_007">RemovalStatus.None) :</span></div>
<div style="position:absolute;left:97.96px;top:273.00px" class="cls_007"><span class="cls_007">this.Count();</span></div>
<div style="position:absolute;left:82.97px;top:300.00px" class="cls_007"><span class="cls_007">public new void Add(T item)</span></div>
<div style="position:absolute;left:82.97px;top:313.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:327.00px" class="cls_007"><span class="cls_007">item.Animatable.OnRemovalStatusChanged +=</span></div>
<div style="position:absolute;left:112.96px;top:340.50px" class="cls_007"><span class="cls_007">Item_OnRemovalStatusChanged;</span></div>
<div style="position:absolute;left:97.96px;top:354.00px" class="cls_007"><span class="cls_007">item.Animatable.AdditionStatus =</span></div>
<div style="position:absolute;left:52.98px;top:367.50px" class="cls_007"><span class="cls_007">AdditionStatus.ReadyToAnimate;</span></div>
<div style="position:absolute;left:97.96px;top:381.00px" class="cls_007"><span class="cls_007">base.Add(item);</span></div>
<div style="position:absolute;left:82.97px;top:394.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:421.50px" class="cls_007"><span class="cls_007">public new virtual void Add(IEnumerable<T> collection)</span></div>
<div style="position:absolute;left:82.97px;top:435.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:448.50px" class="cls_007"><span class="cls_007">foreach (T item in collection) Add(item);</span></div>
<div style="position:absolute;left:82.97px;top:462.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:489.00px" class="cls_007"><span class="cls_007">public new virtual void Add(params T[] items)</span></div>
<div style="position:absolute;left:82.97px;top:502.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:516.00px" class="cls_007"><span class="cls_007">Add(items as IEnumerable<T>);</span></div>
<div style="position:absolute;left:82.97px;top:529.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:556.50px" class="cls_007"><span class="cls_007">public new void Insert(int index, T item)</span></div>
<div style="position:absolute;left:82.97px;top:570.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:583.50px" class="cls_007"><span class="cls_007">item.Animatable.OnRemovalStatusChanged +=</span></div>
<div style="position:absolute;left:112.96px;top:597.00px" class="cls_007"><span class="cls_007">Item_OnRemovalStatusChanged;</span></div>
<div style="position:absolute;left:97.96px;top:610.50px" class="cls_007"><span class="cls_007">item.Animatable.AdditionStatus =</span></div>
<div style="position:absolute;left:52.98px;top:624.00px" class="cls_007"><span class="cls_007">AdditionStatus.ReadyToAnimate;</span></div>
<div style="position:absolute;left:97.96px;top:637.50px" class="cls_007"><span class="cls_007">base.Insert(index, item);</span></div>
<div style="position:absolute;left:82.97px;top:651.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:678.00px" class="cls_007"><span class="cls_007">protected override void ClearItems()</span></div>
<div style="position:absolute;left:82.97px;top:691.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:705.00px" class="cls_007"><span class="cls_007">foreach (T item in this)</span></div>
<div style="position:absolute;left:52.98px;top:718.50px" class="cls_007"><span class="cls_007">item.Animatable.OnRemovalStatusChanged -=</span></div>
<div style="position:absolute;left:112.96px;top:732.00px" class="cls_007"><span class="cls_007">Item_OnRemovalStatusChanged;</span></div>
<div style="position:absolute;left:97.96px;top:745.50px" class="cls_007"><span class="cls_007">base.ClearItems();</span></div>
<div style="position:absolute;left:82.97px;top:759.00px" class="cls_007"><span class="cls_007">}</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:210124px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background264.jpg" width=612 height=792></div>
<div style="position:absolute;left:82.97px;top:3.00px" class="cls_007"><span class="cls_007">public new bool Remove(T item)</span></div>
<div style="position:absolute;left:82.97px;top:16.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:30.00px" class="cls_007"><span class="cls_007">item.Animatable.RemovalStatus = RemovalStatus.ReadyToAnimate;</span></div>
<div style="position:absolute;left:97.96px;top:43.50px" class="cls_007"><span class="cls_007">return true;</span></div>
<div style="position:absolute;left:82.97px;top:57.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:84.00px" class="cls_007"><span class="cls_007">public void Item_OnRemovalStatusChanged(object sender,</span></div>
<div style="position:absolute;left:52.98px;top:97.50px" class="cls_007"><span class="cls_007">EventArgs e)</span></div>
<div style="position:absolute;left:82.97px;top:111.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:124.50px" class="cls_007"><span class="cls_007">Animatable animatable = (Animatable)sender;</span></div>
<div style="position:absolute;left:97.96px;top:138.00px" class="cls_007"><span class="cls_007">if (animatable.RemovalStatus == RemovalStatus.ReadyToRemove</span></div>
<div style="position:absolute;left:52.98px;top:151.50px" class="cls_007"><span class="cls_007">||</span></div>
<div style="position:absolute;left:112.96px;top:165.00px" class="cls_007"><span class="cls_007">(animatable.RemovalStatus == RemovalStatus.ReadyToAnimate</span></div>
<div style="position:absolute;left:52.98px;top:178.50px" class="cls_007"><span class="cls_007">&&</span></div>
<div style="position:absolute;left:112.96px;top:192.00px" class="cls_007"><span class="cls_007">!IsAnimatable))</span></div>
<div style="position:absolute;left:97.96px;top:205.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:112.96px;top:219.00px" class="cls_007"><span class="cls_007">base.Remove(animatable.Owner as T);</span></div>
<div style="position:absolute;left:112.96px;top:232.50px" class="cls_007"><span class="cls_007">animatable.RemovalStatus = RemovalStatus.None;</span></div>
<div style="position:absolute;left:97.96px;top:246.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:259.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:273.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:286.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:319.50px" class="cls_004"><span class="cls_004">Bear in mind that this is a basic example that could be improved in many ways, such as</span></div>
<div style="position:absolute;left:5.00px;top:337.50px" class="cls_004"><span class="cls_004">adding checks for null, enabling addition, removal and insertion capabilities that do not</span></div>
<div style="position:absolute;left:5.00px;top:355.50px" class="cls_004"><span class="cls_004">trigger animations and adding other useful properties.</span></div>
<div style="position:absolute;left:5.00px;top:373.50px" class="cls_004"><span class="cls_004">In this class, we start by specifying that the generic </span><span class="cls_007">T</span><span class="cls_004"> type parameter must implement the</span></div>
<div style="position:absolute;left:5.00px;top:391.50px" class="cls_007"><span class="cls_007">IAnimatable</span><span class="cls_004"> interface. As with our other base collection classes, we ensure that all added</span></div>
<div style="position:absolute;left:5.00px;top:409.50px" class="cls_004"><span class="cls_004">and inserted items call a new </span><span class="cls_007">Add</span><span class="cls_004"> method that attaches our animation related handlers. We</span></div>
<div style="position:absolute;left:5.00px;top:427.50px" class="cls_004"><span class="cls_004">show an example of this in the constructor, but skip the other constructor declarations to</span></div>
<div style="position:absolute;left:5.00px;top:445.50px" class="cls_004"><span class="cls_004">save space.</span></div>
<div style="position:absolute;left:5.00px;top:463.50px" class="cls_004"><span class="cls_004">We then declare an </span><span class="cls_007">IsAnimatable</span><span class="cls_004"> property that we can use to make this collection work</span></div>
<div style="position:absolute;left:5.00px;top:481.50px" class="cls_004"><span class="cls_004">without animation. This property is used in the overridden (or </span><span class="cls_007">new</span><span class="cls_004">) </span><span class="cls_007">Count</span><span class="cls_004"> property, to ensure</span></div>
<div style="position:absolute;left:5.00px;top:499.50px" class="cls_004"><span class="cls_004">that items that are due to be removed are not included in the count of the collection's</span></div>
<div style="position:absolute;left:5.00px;top:517.50px" class="cls_004"><span class="cls_004">children.</span></div>
<div style="position:absolute;left:5.00px;top:535.50px" class="cls_004"><span class="cls_004">In the new </span><span class="cls_007">Add</span><span class="cls_004"> method, we attach a reference of our </span><span class="cls_007">Item_OnRemovalStatusChanged</span></div>
<div style="position:absolute;left:5.00px;top:553.50px" class="cls_004"><span class="cls_004">handler to the </span><span class="cls_007">OnRemovalStatusChanged</span><span class="cls_004"> event of the </span><span class="cls_007">Animatable</span><span class="cls_004"> object of the item being</span></div>
<div style="position:absolute;left:5.00px;top:571.50px" class="cls_004"><span class="cls_004">added. We then set the </span><span class="cls_007">AdditionStatus</span><span class="cls_004"> property of the </span><span class="cls_007">Animatable</span><span class="cls_004"> object to the</span></div>
<div style="position:absolute;left:5.00px;top:589.50px" class="cls_007"><span class="cls_007">ReadyToAnimate</span><span class="cls_004"> member to signal that the object is ready to begin its entrance animation.</span></div>
<div style="position:absolute;left:5.00px;top:607.50px" class="cls_004"><span class="cls_004">As this base collection is extending another base class, we need to remember to call its </span><span class="cls_007">Add</span></div>
<div style="position:absolute;left:5.00px;top:625.50px" class="cls_004"><span class="cls_004">method, passing in the item, so that it can attach its own handler for the item's</span></div>
<div style="position:absolute;left:5.00px;top:643.50px" class="cls_007"><span class="cls_007">PropertyChanged</span><span class="cls_004"> event. The other </span><span class="cls_007">Add</span><span class="cls_004"> overloads enable multiple items to be added to the</span></div>
<div style="position:absolute;left:5.00px;top:661.50px" class="cls_004"><span class="cls_004">collection, but both internally call the first </span><span class="cls_007">Add</span><span class="cls_004"> method. The </span><span class="cls_007">Insert</span><span class="cls_004"> method does the same</span></div>
<div style="position:absolute;left:5.00px;top:679.50px" class="cls_004"><span class="cls_004">as the first </span><span class="cls_007">Add</span><span class="cls_004"> method.</span></div>
<div style="position:absolute;left:5.00px;top:697.50px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">ClearItems</span><span class="cls_004"> method iterates through each item in the collection, detaching the reference</span></div>
<div style="position:absolute;left:5.00px;top:715.50px" class="cls_004"><span class="cls_004">to the </span><span class="cls_007">Item_OnRemovalStatusChanged</span><span class="cls_004"> handler from each before calling the </span><span class="cls_007">ClearItems</span></div>
<div style="position:absolute;left:5.00px;top:733.50px" class="cls_004"><span class="cls_004">method of the base class. As it is, this method could be reserved for removing all items</span></div>
<div style="position:absolute;left:5.00px;top:751.50px" class="cls_004"><span class="cls_004">from the collection without animation, but it would be easy to call the </span><span class="cls_007">Remove</span><span class="cls_004"> method with</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:210926px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background265.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">each item to include animations.</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">Remove</span><span class="cls_004"> method in this class enables us to animate the exit of each item; it doesn't</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">actually remove the item from the collection, but instead sets the </span><span class="cls_007">RemovalStatus</span><span class="cls_004"> property of</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">the item's </span><span class="cls_007">Animatable</span><span class="cls_004"> object to the </span><span class="cls_007">ReadyToAnimate</span><span class="cls_004"> member to signal that the object is</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">ready to begin its exit animation. It then returns true from the method to signify successful</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">removal of the item.</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">Finally, we get to the </span><span class="cls_007">Item_OnRemovalStatusChanged</span><span class="cls_004"> event handler, which is the next major</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">part in enabling exit animations. In it, we cast the </span><span class="cls_007">sender</span><span class="cls_004"> input parameter to an instance of</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">our </span><span class="cls_007">Animatable</span><span class="cls_004"> class. Remember that it passes itself as the </span><span class="cls_007">sender</span><span class="cls_004"> parameter when raising</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">the event.</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">We then use it to determine whether its </span><span class="cls_007">RemovalStatus</span><span class="cls_004"> property is set to the</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_007"><span class="cls_007">ReadyToRemove</span><span class="cls_004"> member, or both its </span><span class="cls_007">RemovalStatus</span><span class="cls_004"> property is set to </span><span class="cls_007">ReadyToAnimate</span><span class="cls_004"> and</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">the collection is not animatable. If either condition is true, we finally call the </span><span class="cls_007">Remove</span><span class="cls_004"> method</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">of the base class to actually remove the item from the collection and set the </span><span class="cls_007">RemovalStatus</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">property to </span><span class="cls_007">None</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">In this way, when the collection is set to be not animatable and the </span><span class="cls_007">Remove</span><span class="cls_004"> method is called,</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">the item is immediately removed and the </span><span class="cls_007">Animatable</span><span class="cls_004"> object's </span><span class="cls_007">RemovalStatus</span><span class="cls_004"> property is set</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">to the </span><span class="cls_007">None</span><span class="cls_004"> member in the </span><span class="cls_007">Item_OnRemovalStatusChanged</span><span class="cls_004"> handler. If you remember, the</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_007"><span class="cls_007">OnRemovalStatusChanged</span><span class="cls_004"> event gets raised when the </span><span class="cls_007">RemovalStatus</span><span class="cls_004"> property value is</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_004"><span class="cls_004">changed.</span></div>
<div style="position:absolute;left:5.00px;top:363.75px" class="cls_004"><span class="cls_004">However, we're still missing part of this puzzle. What sets the </span><span class="cls_007">Animatable</span><span class="cls_004"> object's</span></div>
<div style="position:absolute;left:5.00px;top:381.75px" class="cls_007"><span class="cls_007">RemovalStatus</span><span class="cls_004"> property to the </span><span class="cls_007">ReadyToRemove</span><span class="cls_004"> member to remove each item? We will need</span></div>
<div style="position:absolute;left:5.00px;top:399.75px" class="cls_004"><span class="cls_004">to update our animated panel to accomplish this task and to do this, it will need to maintain</span></div>
<div style="position:absolute;left:5.00px;top:417.75px" class="cls_004"><span class="cls_004">a collection of the elements that need to be removed and signal the collection to remove</span></div>
<div style="position:absolute;left:5.00px;top:435.75px" class="cls_004"><span class="cls_004">them once their exit animations complete.</span></div>
<div style="position:absolute;left:52.98px;top:459.00px" class="cls_007"><span class="cls_007">private List<UIElement> elementsToBeRemoved = new List<UIElement></span></div>
<div style="position:absolute;left:52.98px;top:472.50px" class="cls_007"><span class="cls_007">();</span></div>
<div style="position:absolute;left:5.00px;top:492.75px" class="cls_004"><span class="cls_004">We can use the </span><span class="cls_007">Storyboard.Completed</span><span class="cls_004"> event to notify us when the animation is complete</span></div>
<div style="position:absolute;left:5.00px;top:510.75px" class="cls_004"><span class="cls_004">and then signal to remove the item at that point, by setting the </span><span class="cls_007">Animatable</span><span class="cls_004"> object's</span></div>
<div style="position:absolute;left:5.00px;top:528.75px" class="cls_007"><span class="cls_007">RemovalStatus</span><span class="cls_004"> property to the </span><span class="cls_007">ReadyToRemove</span><span class="cls_004"> member. Let's take a look at the required</span></div>
<div style="position:absolute;left:5.00px;top:546.75px" class="cls_004"><span class="cls_004">changes to our animated panel. First, we need to add the following using declarations.</span></div>
<div style="position:absolute;left:52.98px;top:570.00px" class="cls_007"><span class="cls_007">using System.Collections.Generic;</span></div>
<div style="position:absolute;left:52.98px;top:583.50px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.DataModels.Enums;</span></div>
<div style="position:absolute;left:52.98px;top:597.00px" class="cls_007"><span class="cls_007">using Animatable =</span></div>
<div style="position:absolute;left:52.98px;top:610.50px" class="cls_007"><span class="cls_007">CompanyName.ApplicationName.DataModels.Animatable;</span></div>
<div style="position:absolute;left:52.98px;top:624.00px" class="cls_007"><span class="cls_007">using IAnimatable =</span></div>
<div style="position:absolute;left:67.97px;top:637.50px" class="cls_007"><span class="cls_007">CompanyName.ApplicationName.DataModels.Interfaces.IAnimatable;</span></div>
<div style="position:absolute;left:5.00px;top:657.75px" class="cls_004"><span class="cls_004">Next, we need to replace the call to the </span><span class="cls_007">AnimatePosition</span><span class="cls_004"> method from the original</span></div>
<div style="position:absolute;left:5.00px;top:675.75px" class="cls_007"><span class="cls_007">ArrangeOverride</span><span class="cls_004"> method with the following line.</span></div>
<div style="position:absolute;left:52.98px;top:699.00px" class="cls_007"><span class="cls_007">BeginAnimations(child, finalSize, endPosition);</span></div>
<div style="position:absolute;left:5.00px;top:719.25px" class="cls_004"><span class="cls_004">We then need to add the following additional methods after the </span><span class="cls_007">ArrangeOverride</span><span class="cls_004"> method.</span></div>
<div style="position:absolute;left:52.98px;top:742.50px" class="cls_007"><span class="cls_007">private void BeginAnimations(UIElement child, Size finalSize,</span></div>
<div style="position:absolute;left:67.97px;top:756.00px" class="cls_007"><span class="cls_007">Point endPosition)</span></div>
<div style="position:absolute;left:52.98px;top:769.50px" class="cls_007"><span class="cls_007">{</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:211728px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background266.jpg" width=612 height=792></div>
<div style="position:absolute;left:67.97px;top:3.00px" class="cls_007"><span class="cls_007">FrameworkElement frameworkChild = (FrameworkElement)child;</span></div>
<div style="position:absolute;left:67.97px;top:16.50px" class="cls_007"><span class="cls_007">if (frameworkChild.DataContext is IAnimatable)</span></div>
<div style="position:absolute;left:67.97px;top:30.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:43.50px" class="cls_007"><span class="cls_007">Animatable animatable =</span></div>
<div style="position:absolute;left:97.96px;top:57.00px" class="cls_007"><span class="cls_007">((IAnimatable)frameworkChild.DataContext).Animatable;</span></div>
<div style="position:absolute;left:82.97px;top:70.50px" class="cls_007"><span class="cls_007">animatable.OnRemovalStatusChanged -=</span></div>
<div style="position:absolute;left:52.98px;top:84.00px" class="cls_007"><span class="cls_007">Item_OnRemovalStatusChanged;</span></div>
<div style="position:absolute;left:82.97px;top:97.50px" class="cls_007"><span class="cls_007">animatable.OnRemovalStatusChanged +=</span></div>
<div style="position:absolute;left:52.98px;top:111.00px" class="cls_007"><span class="cls_007">Item_OnRemovalStatusChanged;</span></div>
<div style="position:absolute;left:82.97px;top:124.50px" class="cls_007"><span class="cls_007">if (animatable.AdditionStatus == AdditionStatus.DoNotAnimate)</span></div>
<div style="position:absolute;left:82.97px;top:138.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:151.50px" class="cls_007"><span class="cls_007">child.Arrange(new Rect(endPosition.X, endPosition.Y,</span></div>
<div style="position:absolute;left:112.96px;top:165.00px" class="cls_007"><span class="cls_007">frameworkChild.ActualWidth, frameworkChild.ActualHeight));</span></div>
<div style="position:absolute;left:82.97px;top:178.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:192.00px" class="cls_007"><span class="cls_007">else if (animatable.AdditionStatus ==</span></div>
<div style="position:absolute;left:52.98px;top:205.50px" class="cls_007"><span class="cls_007">AdditionStatus.ReadyToAnimate)</span></div>
<div style="position:absolute;left:82.97px;top:219.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:232.50px" class="cls_007"><span class="cls_007">AnimateEntry(child, endPosition);</span></div>
<div style="position:absolute;left:97.96px;top:246.00px" class="cls_007"><span class="cls_007">animatable.AdditionStatus = AdditionStatus.Added;</span></div>
<div style="position:absolute;left:97.96px;top:259.50px" class="cls_007"><span class="cls_007">animatable.TransitionStatus =</span></div>
<div style="position:absolute;left:52.98px;top:273.00px" class="cls_007"><span class="cls_007">TransitionStatus.ReadyToAnimate;</span></div>
<div style="position:absolute;left:82.97px;top:286.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:300.00px" class="cls_007"><span class="cls_007">else if (animatable.RemovalStatus ==</span></div>
<div style="position:absolute;left:52.98px;top:313.50px" class="cls_007"><span class="cls_007">RemovalStatus.ReadyToAnimate)</span></div>
<div style="position:absolute;left:97.96px;top:327.00px" class="cls_007"><span class="cls_007">AnimateExit(child, endPosition, finalSize);</span></div>
<div style="position:absolute;left:82.97px;top:340.50px" class="cls_007"><span class="cls_007">else if (animatable.TransitionStatus ==</span></div>
<div style="position:absolute;left:97.96px;top:354.00px" class="cls_007"><span class="cls_007">TransitionStatus.ReadyToAnimate)</span></div>
<div style="position:absolute;left:97.96px;top:367.50px" class="cls_007"><span class="cls_007">AnimateTransition(child, endPosition);</span></div>
<div style="position:absolute;left:67.97px;top:381.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:394.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:421.50px" class="cls_007"><span class="cls_007">private void Item_OnRemovalStatusChanged(object sender, EventArgs</span></div>
<div style="position:absolute;left:52.98px;top:435.00px" class="cls_007"><span class="cls_007">e)</span></div>
<div style="position:absolute;left:52.98px;top:448.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:462.00px" class="cls_007"><span class="cls_007">if (((Animatable)sender).RemovalStatus ==</span></div>
<div style="position:absolute;left:52.98px;top:475.50px" class="cls_007"><span class="cls_007">RemovalStatus.ReadyToAnimate)</span></div>
<div style="position:absolute;left:82.97px;top:489.00px" class="cls_007"><span class="cls_007">InvalidateArrange();</span></div>
<div style="position:absolute;left:52.98px;top:502.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:529.50px" class="cls_007"><span class="cls_007">private void AnimateEntry(UIElement child, Point endPosition)</span></div>
<div style="position:absolute;left:52.98px;top:543.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:556.50px" class="cls_007"><span class="cls_007">AnimatePosition(child, endPosition,</span></div>
<div style="position:absolute;left:52.98px;top:570.00px" class="cls_007"><span class="cls_007">TimeSpan.FromMilliseconds(300));</span></div>
<div style="position:absolute;left:52.98px;top:583.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:610.50px" class="cls_007"><span class="cls_007">private void AnimateTransition(UIElement child, Point endPosition)</span></div>
<div style="position:absolute;left:52.98px;top:624.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:637.50px" class="cls_007"><span class="cls_007">AnimatePosition(child, endPosition,</span></div>
<div style="position:absolute;left:52.98px;top:651.00px" class="cls_007"><span class="cls_007">TimeSpan.FromMilliseconds(300));</span></div>
<div style="position:absolute;left:52.98px;top:664.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:691.50px" class="cls_007"><span class="cls_007">private void AnimateExit(UIElement child, Point startPosition,</span></div>
<div style="position:absolute;left:67.97px;top:705.00px" class="cls_007"><span class="cls_007">Size finalSize)</span></div>
<div style="position:absolute;left:52.98px;top:718.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:732.00px" class="cls_007"><span class="cls_007">SetZIndex(child, 100);</span></div>
<div style="position:absolute;left:67.97px;top:745.50px" class="cls_007"><span class="cls_007">Point endPosition =</span></div>
<div style="position:absolute;left:82.97px;top:759.00px" class="cls_007"><span class="cls_007">new Point(startPosition.X + finalSize.Width, startPosition.Y);</span></div>
<div style="position:absolute;left:67.97px;top:772.50px" class="cls_007"><span class="cls_007">AnimatePosition(child, startPosition, endPosition,</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:212530px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background267.jpg" width=612 height=792></div>
<div style="position:absolute;left:82.97px;top:3.00px" class="cls_007"><span class="cls_007">TimeSpan.FromMilliseconds(300), RemovalAnimation_Completed);</span></div>
<div style="position:absolute;left:67.97px;top:16.50px" class="cls_007"><span class="cls_007">elementsToBeRemoved.Add(child);</span></div>
<div style="position:absolute;left:52.98px;top:30.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:57.00px" class="cls_007"><span class="cls_007">private void AnimatePosition(UIElement child, Point startPosition,</span></div>
<div style="position:absolute;left:67.97px;top:70.50px" class="cls_007"><span class="cls_007">Point endPosition, TimeSpan animationDuration,</span></div>
<div style="position:absolute;left:67.97px;top:84.00px" class="cls_007"><span class="cls_007">EventHandler animationCompletedHandler)</span></div>
<div style="position:absolute;left:52.98px;top:97.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:111.00px" class="cls_007"><span class="cls_007">if (startPosition.X != endPosition.X)</span></div>
<div style="position:absolute;left:67.97px;top:124.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:138.00px" class="cls_007"><span class="cls_007">DoubleAnimation xAnimation = new</span></div>
<div style="position:absolute;left:52.98px;top:151.50px" class="cls_007"><span class="cls_007">DoubleAnimation(startPosition.X,</span></div>
<div style="position:absolute;left:97.96px;top:165.00px" class="cls_007"><span class="cls_007">endPosition.X, animationDuration);</span></div>
<div style="position:absolute;left:82.97px;top:178.50px" class="cls_007"><span class="cls_007">xAnimation.AccelerationRatio = 1.0;</span></div>
<div style="position:absolute;left:82.97px;top:192.00px" class="cls_007"><span class="cls_007">if (animationCompletedHandler != null)</span></div>
<div style="position:absolute;left:97.96px;top:205.50px" class="cls_007"><span class="cls_007">xAnimation.Completed += animationCompletedHandler;</span></div>
<div style="position:absolute;left:82.97px;top:219.00px" class="cls_007"><span class="cls_007">GetTranslateTransform(child).BeginAnimation(</span></div>
<div style="position:absolute;left:97.96px;top:232.50px" class="cls_007"><span class="cls_007">TranslateTransform.XProperty, xAnimation);</span></div>
<div style="position:absolute;left:67.97px;top:246.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:259.50px" class="cls_007"><span class="cls_007">if (startPosition.Y != endPosition.Y)</span></div>
<div style="position:absolute;left:67.97px;top:273.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:286.50px" class="cls_007"><span class="cls_007">DoubleAnimation yAnimation = new</span></div>
<div style="position:absolute;left:52.98px;top:300.00px" class="cls_007"><span class="cls_007">DoubleAnimation(startPosition.Y,</span></div>
<div style="position:absolute;left:97.96px;top:313.50px" class="cls_007"><span class="cls_007">endPosition.Y, animationDuration);</span></div>
<div style="position:absolute;left:82.97px;top:327.00px" class="cls_007"><span class="cls_007">yAnimation.AccelerationRatio = 1.0;</span></div>
<div style="position:absolute;left:82.97px;top:340.50px" class="cls_007"><span class="cls_007">if (startPosition.X == endPosition.X &&</span></div>
<div style="position:absolute;left:52.98px;top:354.00px" class="cls_007"><span class="cls_007">animationCompletedHandler !=</span></div>
<div style="position:absolute;left:97.96px;top:367.50px" class="cls_007"><span class="cls_007">null) yAnimation.Completed += animationCompletedHandler;</span></div>
<div style="position:absolute;left:82.97px;top:381.00px" class="cls_007"><span class="cls_007">GetTranslateTransform(child).BeginAnimation(</span></div>
<div style="position:absolute;left:97.96px;top:394.50px" class="cls_007"><span class="cls_007">TranslateTransform.YProperty, yAnimation);</span></div>
<div style="position:absolute;left:67.97px;top:408.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:421.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:448.50px" class="cls_007"><span class="cls_007">private void RemovalAnimation_Completed(object sender, EventArgs e)</span></div>
<div style="position:absolute;left:52.98px;top:462.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:475.50px" class="cls_007"><span class="cls_007">for (int index = elementsToBeRemoved.Count - 1; index >= 0;</span></div>
<div style="position:absolute;left:52.98px;top:489.00px" class="cls_007"><span class="cls_007">index--)</span></div>
<div style="position:absolute;left:67.97px;top:502.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:516.00px" class="cls_007"><span class="cls_007">FrameworkElement frameworkElement =</span></div>
<div style="position:absolute;left:97.96px;top:529.50px" class="cls_007"><span class="cls_007">elementsToBeRemoved[index] as FrameworkElement;</span></div>
<div style="position:absolute;left:82.97px;top:543.00px" class="cls_007"><span class="cls_007">if (frameworkElement.DataContext is IAnimatable)</span></div>
<div style="position:absolute;left:82.97px;top:556.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:52.98px;top:583.50px" class="cls_007"><span class="cls_007">((IAnimatable)frameworkElement.DataContext).Animatable.RemovalStatu</span></div>
<div style="position:absolute;left:52.98px;top:597.00px" class="cls_007"><span class="cls_007">s</span></div>
<div style="position:absolute;left:112.96px;top:610.50px" class="cls_007"><span class="cls_007">= RemovalStatus.ReadyToRemove;</span></div>
<div style="position:absolute;left:97.96px;top:624.00px" class="cls_007"><span class="cls_007">elementsToBeRemoved.Remove(frameworkElement);</span></div>
<div style="position:absolute;left:82.97px;top:637.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:651.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:664.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:697.50px" class="cls_004"><span class="cls_004">Let's examine this new code. First, we have the </span><span class="cls_007">BeginAnimations</span><span class="cls_004"> method, in which we cast</span></div>
<div style="position:absolute;left:5.00px;top:715.50px" class="cls_004"><span class="cls_004">the container control to a </span><span class="cls_007">FrameworkElement</span><span class="cls_004">, so that we can access its </span><span class="cls_007">DataContext</span></div>
<div style="position:absolute;left:5.00px;top:733.50px" class="cls_004"><span class="cls_004">property. Our data object is accessed from this property and we cast it to an </span><span class="cls_007">IAnimatable</span></div>
<div style="position:absolute;left:5.00px;top:751.50px" class="cls_004"><span class="cls_004">instance, so that we can access the </span><span class="cls_007">Animatable</span><span class="cls_004"> object via its </span><span class="cls_007">Animatable</span><span class="cls_004"> property.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:213332px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background268.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">We then remove our </span><span class="cls_007">Item_OnRemovalStatusChanged</span><span class="cls_004"> event handler from the</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_007"><span class="cls_007">OnRemovalStatusChanged</span><span class="cls_004"> event before re-attaching it, to ensure that only a single handler is</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">attached, regardless of how many times each child passes through this method.</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">If the </span><span class="cls_007">AdditionStatus</span><span class="cls_004"> property is set to </span><span class="cls_007">DoNotAnimate</span><span class="cls_004">, we arrange the item at its end</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">position immediately and without animation, while if it is set to </span><span class="cls_007">ReadyToAnimate</span><span class="cls_004">, we call the</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_007"><span class="cls_007">AnimateEntry</span><span class="cls_004"> method and then set the </span><span class="cls_007">AdditionStatus</span><span class="cls_004"> property to </span><span class="cls_007">Added</span><span class="cls_004">. Finally, if the</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_007"><span class="cls_007">RemovalStatus</span><span class="cls_004"> property is set to </span><span class="cls_007">ReadyToAnimate</span><span class="cls_004">, we call the </span><span class="cls_007">AnimateExit</span><span class="cls_004"> method.</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">In the </span><span class="cls_007">Item_OnRemovalStatusChanged</span><span class="cls_004"> event handler, we call the panel's </span><span class="cls_007">InvalidateArrange</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">method if the </span><span class="cls_007">RemovalStatus</span><span class="cls_004"> property is set to </span><span class="cls_007">ReadyToAnimate</span><span class="cls_004">. This is another essential</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">part of the exit animation strategy and it requests the layout system to call the</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_007"><span class="cls_007">ArrangeOverride</span><span class="cls_004"> method, thereby triggering the starting of the exit animation(s).</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">Remember that the </span><span class="cls_007">OnRemovalStatusChanged</span><span class="cls_004"> event gets raised when the value of the</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_007"><span class="cls_007">RemovalStatus</span><span class="cls_004"> property is changed and that it is set to the </span><span class="cls_007">ReadyToAnimate</span><span class="cls_004"> member in the</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_007"><span class="cls_007">Remove</span><span class="cls_004"> method of the </span><span class="cls_007">BaseAnimatableCollection<T></span><span class="cls_004"> class. That raises the event and this</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">event handler starts the animations in response.</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">AnimateEntry</span><span class="cls_004"> method simply calls the original, unchanged </span><span class="cls_007">AnimatePosition</span><span class="cls_004"> method</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">from our first animated panel attempt. The </span><span class="cls_007">AnimateExit</span><span class="cls_004"> method takes an additional</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_007"><span class="cls_007">startPosition</span><span class="cls_004"> input parameter, which represents the current position of each item within</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_004"><span class="cls_004">the panel.</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_004"><span class="cls_004">We start by setting the </span><span class="cls_007">Panel.SetZIndex</span><span class="cls_004"> Attached Property to a value of </span><span class="cls_007">100</span><span class="cls_004"> for each child,</span></div>
<div style="position:absolute;left:5.00px;top:363.75px" class="cls_004"><span class="cls_004">to ensure that their animated departure is rendered above, or over the top of, the remaining</span></div>
<div style="position:absolute;left:5.00px;top:381.75px" class="cls_004"><span class="cls_004">items. We then calculate the end position of the animation using the start position and the</span></div>
<div style="position:absolute;left:5.00px;top:399.75px" class="cls_004"><span class="cls_004">size of the panel.</span></div>
<div style="position:absolute;left:5.00px;top:417.75px" class="cls_004"><span class="cls_004">Next, we call an overload of the </span><span class="cls_007">AnimatePosition</span><span class="cls_004"> method, passing in our child, start and</span></div>
<div style="position:absolute;left:5.00px;top:435.75px" class="cls_004"><span class="cls_004">end positions, animation duration and an event handler as parameters. After the child item's</span></div>
<div style="position:absolute;left:5.00px;top:453.75px" class="cls_004"><span class="cls_004">position animation has been started, the child is added to the </span><span class="cls_007">elementsToBeRemoved</span></div>
<div style="position:absolute;left:5.00px;top:471.75px" class="cls_004"><span class="cls_004">collection.</span></div>
<div style="position:absolute;left:5.00px;top:489.75px" class="cls_004"><span class="cls_004">In the </span><span class="cls_007">AnimatePosition</span><span class="cls_004"> method, we first check that our start and end positions are</span></div>
<div style="position:absolute;left:5.00px;top:507.75px" class="cls_004"><span class="cls_004">different, before creating and starting our </span><span class="cls_007">DoubleAnimation</span><span class="cls_004"> objects. If the </span><span class="cls_007">X</span><span class="cls_004"> values are</span></div>
<div style="position:absolute;left:5.00px;top:525.75px" class="cls_004"><span class="cls_004">different and the event handler input parameter is not null, then we attach it to the</span></div>
<div style="position:absolute;left:5.00px;top:543.75px" class="cls_007"><span class="cls_007">Completed</span><span class="cls_004"> event of the </span><span class="cls_007">xAnimation</span><span class="cls_004"> object before starting its animation.</span></div>
<div style="position:absolute;left:5.00px;top:561.75px" class="cls_004"><span class="cls_004">If the </span><span class="cls_007">Y</span><span class="cls_004"> values are different and the event handler input parameter is not null and the event</span></div>
<div style="position:absolute;left:5.00px;top:579.75px" class="cls_004"><span class="cls_004">handler was not already attached to the </span><span class="cls_007">xAnimation</span><span class="cls_004"> object, then we attach it to the</span></div>
<div style="position:absolute;left:5.00px;top:597.75px" class="cls_007"><span class="cls_007">Completed</span><span class="cls_004"> event of the</span><span class="cls_007"> yAnimation</span><span class="cls_004"> object before starting its animation. Note that we only</span></div>
<div style="position:absolute;left:5.00px;top:615.75px" class="cls_004"><span class="cls_004">need to attach one handler to this event, because we only have one object to remove from</span></div>
<div style="position:absolute;left:5.00px;top:633.75px" class="cls_004"><span class="cls_004">the collection.</span></div>
<div style="position:absolute;left:5.00px;top:651.75px" class="cls_004"><span class="cls_004">Also note that we set the </span><span class="cls_007">AccelerationRatio</span><span class="cls_004"> property to </span><span class="cls_007">1.0</span><span class="cls_004"> in this overload, so that the</span></div>
<div style="position:absolute;left:5.00px;top:669.75px" class="cls_004"><span class="cls_004">item accelerates off screen. However, in a business application framework, we would want</span></div>
<div style="position:absolute;left:5.00px;top:687.75px" class="cls_004"><span class="cls_004">to keep our animation properties in sync and so, we would probably set the</span></div>
<div style="position:absolute;left:5.00px;top:705.75px" class="cls_007"><span class="cls_007">AccelerationRatio</span><span class="cls_004"> property to </span><span class="cls_007">1.0</span><span class="cls_004"> on the animation objects in the original</span></div>
<div style="position:absolute;left:5.00px;top:723.75px" class="cls_007"><span class="cls_007">AnimatePosition</span><span class="cls_004"> method as well.</span></div>
<div style="position:absolute;left:5.00px;top:741.75px" class="cls_004"><span class="cls_004">The last piece of the puzzle is the </span><span class="cls_007">RemovalAnimation_Completed</span><span class="cls_004"> event handling method.</span></div>
<div style="position:absolute;left:5.00px;top:759.75px" class="cls_004"><span class="cls_004">This method gets called when the exit animation has completed and iterates through the</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:214134px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background269.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_007"><span class="cls_007">elementsToBeRemoved</span><span class="cls_004"> collection. If any element to remove implements the </span><span class="cls_007">IAnimatable</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">interface, its </span><span class="cls_007">Animatable</span><span class="cls_004"> object's </span><span class="cls_007">RemovalStatus</span><span class="cls_004"> property is set to the </span><span class="cls_007">ReadyToRemove</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">member.</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">If you remember, this raises the </span><span class="cls_007">OnRemovalStatusChanged</span><span class="cls_004"> event, which is handled by the</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_007"><span class="cls_007">Item_OnRemovalStatusChanged</span><span class="cls_004"> event handler in the </span><span class="cls_007">BaseAnimatableCollection</span><span class="cls_004"> class. In</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">that method, the </span><span class="cls_007">Animatable</span><span class="cls_004"> object's </span><span class="cls_007">RemovalStatus</span><span class="cls_004"> property is checked for the</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_007"><span class="cls_007">ReadyToRemove</span><span class="cls_004"> member and if found, the owning item is actually removed from the</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">collection.</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">And so, to summarize; the </span><span class="cls_007">Remove</span><span class="cls_004"> method of the animation collection is called, but instead</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">of removing the item, it sets a property on it, which raises an event that is handled by the</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">animated panel; the panel then starts the exit animation and when completed, it raises an</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">event that is handled by the collection class and results in the item actually being removed</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">from the collection.</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">While this animated panel is entirely usable as it is, there are many ways that it could be</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">further improved. One important thing that we could do would be to extract all of the</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">properties and animation code from this class and put them into a base </span><span class="cls_007">AnimatedPanel</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">class. In this way, we could reuse this class when creating other types of animated panel,</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">such as an </span><span class="cls_007">AnimatedWrapPanel</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_004"><span class="cls_004">We could then further extend the base class by exposing additional animation properties, so</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_004"><span class="cls_004">that users of our panel could have more control over the animations that it provides. For</span></div>
<div style="position:absolute;left:5.00px;top:363.75px" class="cls_004"><span class="cls_004">example, we could declare </span><span class="cls_007">VerticalContentAlignment</span><span class="cls_004"> and </span><span class="cls_007">HorizontalContentAlignment</span></div>
<div style="position:absolute;left:5.00px;top:381.75px" class="cls_004"><span class="cls_004">properties to dictate how our panel items should be aligned in the panel.</span></div>
<div style="position:absolute;left:5.00px;top:399.75px" class="cls_004"><span class="cls_004">Additionally, we could add </span><span class="cls_007">EntryAnimationDirection</span><span class="cls_004"> and </span><span class="cls_007">ExitAnimationDirection</span></div>
<div style="position:absolute;left:5.00px;top:417.75px" class="cls_004"><span class="cls_004">properties to specify which direction to animate our panel items as they are added and</span></div>
<div style="position:absolute;left:5.00px;top:435.75px" class="cls_004"><span class="cls_004">removed from the panel. We could also enable different types of animation, such as fading</span></div>
<div style="position:absolute;left:5.00px;top:453.75px" class="cls_004"><span class="cls_004">or spinning, by animating the </span><span class="cls_007">Opacity</span><span class="cls_004"> property, or the </span><span class="cls_007">Angle</span><span class="cls_004"> property of a</span></div>
<div style="position:absolute;left:5.00px;top:471.75px" class="cls_007"><span class="cls_007">RotationTransform</span><span class="cls_004"> element.</span></div>
<div style="position:absolute;left:5.00px;top:489.75px" class="cls_004"><span class="cls_004">Furthermore, we could add </span><span class="cls_007">EntryAnimationDuration</span><span class="cls_004"> and </span><span class="cls_007">ExitAnimationDuration</span></div>
<div style="position:absolute;left:5.00px;top:507.75px" class="cls_004"><span class="cls_004">properties to specify the length of time that each animation should take, rather than</span></div>
<div style="position:absolute;left:5.00px;top:525.75px" class="cls_004"><span class="cls_004">hardcoding values directly into our panel. There really is no limit to what functionality that we</span></div>
<div style="position:absolute;left:5.00px;top:543.75px" class="cls_004"><span class="cls_004">can provide with our application framework panels, other than the limitations dictated by the</span></div>
<div style="position:absolute;left:5.00px;top:561.75px" class="cls_004"><span class="cls_004">end users' computer hardware.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:214936px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background270.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_008"><span class="cls_008">Summary</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">In this chapter, we've investigated the variety of animation possibilities that WPF provides</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">us with, primarily focusing on XAML and the more usable options. We've discovered the</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">finer details of timelines and also explored how we can incorporate animation into our</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">application framework, so that its users can easily leverage the power of animations without</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">having to know anything about them.</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">In the next chapter, we will look at a number of ways that we can improve the overall look</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">and feel of our applications, from providing consistent application styles and icons to</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">examining a number of techniques for creating rich graphics.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:215738px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background271.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_002"><span class="cls_002">Chapter 7. Creating Visually Appealing</span></div>
<div style="position:absolute;left:5.00px;top:39.01px" class="cls_002"><span class="cls_002">User Interfaces</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">While it is simple to add form elements to a View, it takes somewhat more to produce an</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">application that looks visually appealing. Luckily, WPF provides us with many features that</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">can help us to achieve this goal, such as gradient brushes, rounded corners, opacity</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">control, layered visuals and animations.</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">In this chapter, we'll be looking at a number of ways of using these elements to greatly</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">improve the visual aspect of our applications. We'll investigate solutions that are simple to</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">implement, using style properties, and others that will take more work, such as animations</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">and custom controls.</span></div>
<div style="position:absolute;left:5.00px;top:219.01px" class="cls_008"><span class="cls_008">Styling applications consistently</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">One of the easiest ways to make our applications stand out is to make them look unique.</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">This can be achieved by defining custom styles for the controls that we use in it. However, if</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">we decide to style our controls, it is essential that we style all of the controls that we use,</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">as a half styled application can often look worse than an application that merely uses the</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_004"><span class="cls_004">default styles.</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_004"><span class="cls_004">It is therefore absolutely essential that we design our application control styles consistently,</span></div>
<div style="position:absolute;left:5.00px;top:363.75px" class="cls_004"><span class="cls_004">in order to attain a professional look for our application. In this section, we'll discuss a</span></div>
<div style="position:absolute;left:5.00px;top:381.75px" class="cls_004"><span class="cls_004">number of tips and tricks to help us to implement these application styles.</span></div>
<div style="position:absolute;left:5.00px;top:399.01px" class="cls_011"><span class="cls_011">Overriding default control styles</span></div>
<div style="position:absolute;left:5.00px;top:429.00px" class="cls_004"><span class="cls_004">When providing custom styles for our application controls, this typically requires us to define</span></div>
<div style="position:absolute;left:5.00px;top:447.00px" class="cls_004"><span class="cls_004">a new </span><span class="cls_007">ControlTemplate</span><span class="cls_004"> element for each of them. As these can often be very large, it is</span></div>
<div style="position:absolute;left:5.00px;top:465.00px" class="cls_004"><span class="cls_004">customary to declare them in a separate resource file and merge it with the application</span></div>
<div style="position:absolute;left:5.00px;top:483.00px" class="cls_004"><span class="cls_004">resources in the </span><span class="cls_007">App.xaml</span><span class="cls_004"> file, as shown in the previous chapter.</span></div>
<div style="position:absolute;left:5.00px;top:501.00px" class="cls_004"><span class="cls_004">Before starting this task, we need to plan how we want our controls to look and then apply</span></div>
<div style="position:absolute;left:5.00px;top:519.00px" class="cls_004"><span class="cls_004">this same look to each control. Another mistake would be to customize different controls</span></div>
<div style="position:absolute;left:5.00px;top:537.00px" class="cls_004"><span class="cls_004">with different styles, as consistency is key to providing a professional look. For example, if</span></div>
<div style="position:absolute;left:5.00px;top:555.00px" class="cls_004"><span class="cls_004">we want our single line textboxes to be a certain height, then we should also define our</span></div>
<div style="position:absolute;left:5.00px;top:573.00px" class="cls_004"><span class="cls_004">other controls to be the same height.</span></div>
<div style="position:absolute;left:5.00px;top:591.00px" class="cls_004"><span class="cls_004">The custom styles that we declare for our controls can be part of our application</span></div>
<div style="position:absolute;left:5.00px;top:609.00px" class="cls_004"><span class="cls_004">framework. If we define them without naming them via the </span><span class="cls_007">x:Key</span><span class="cls_004"> directive, they will be</span></div>
<div style="position:absolute;left:5.00px;top:627.00px" class="cls_004"><span class="cls_004">implicitly applied and so the developers that utilize our application framework need not</span></div>
<div style="position:absolute;left:5.00px;top:645.00px" class="cls_004"><span class="cls_004">concern themselves with the look of each control, effectively freeing them up to concentrate</span></div>
<div style="position:absolute;left:5.00px;top:663.00px" class="cls_004"><span class="cls_004">on aggregating them into the various Views.</span></div>
<div style="position:absolute;left:5.00px;top:681.00px" class="cls_004"><span class="cls_004">The first thing to do before starting to design our custom styles is to define a small range of</span></div>
<div style="position:absolute;left:5.00px;top:699.00px" class="cls_004"><span class="cls_004">colors that we will use in our application. Using too many colors in an application can make</span></div>
<div style="position:absolute;left:5.00px;top:717.00px" class="cls_004"><span class="cls_004">it look less professional, so we should chose a few shades of a small number of colors to</span></div>
<div style="position:absolute;left:5.00px;top:735.00px" class="cls_004"><span class="cls_004">use. There are a number of online tools that can help us to pick a color palette to use.</span></div>
<div style="position:absolute;left:5.00px;top:753.00px" class="cls_004"><span class="cls_004">Once we have chosen our application colors, we should declare them first as </span><span class="cls_007">Color</span><span class="cls_004"> objects</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:216540px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background272.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">in the </span><span class="cls_007">App.xaml</span><span class="cls_004"> file and then declare brush elements that use them, as most controls use</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">brushes rather than colors. This has two benefits; using only these colors will promote</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">consistency and if we ever need to change a color, we only need to change it in a single</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">place.</span></div>
<div style="position:absolute;left:52.98px;top:81.00px" class="cls_007"><span class="cls_007"><Color x:Key="ReadOnlyColor" A="255" R="88" G="88" B="88" /></span></div>
<div style="position:absolute;left:52.98px;top:108.00px" class="cls_007"><span class="cls_007"><SolidColorBrush x:Key="ReadOnlyBrush"</span></div>
<div style="position:absolute;left:67.97px;top:121.50px" class="cls_007"><span class="cls_007">Color="{StaticResource ReadOnlyColor}" /></span></div>
<div style="position:absolute;left:5.00px;top:141.75px" class="cls_004"><span class="cls_004">It is often a good idea to also define multiple named styles for the most common types of</span></div>
<div style="position:absolute;left:5.00px;top:159.75px" class="cls_004"><span class="cls_004">controls. For example, having a </span><span class="cls_007">Label</span><span class="cls_004"> style for </span><span class="cls_007">TextBlock</span><span class="cls_004"> elements, that right aligns them</span></div>
<div style="position:absolute;left:5.00px;top:177.75px" class="cls_004"><span class="cls_004">and adds suitable margins, or a </span><span class="cls_007">Heading</span><span class="cls_004"> style that sets a larger font size and heavier font</span></div>
<div style="position:absolute;left:5.00px;top:195.75px" class="cls_004"><span class="cls_004">weight. Providing the developers with a set of predefined styles helps to make the</span></div>
<div style="position:absolute;left:5.00px;top:213.75px" class="cls_004"><span class="cls_004">application as a whole look consistent.</span></div>
<div style="position:absolute;left:5.00px;top:231.75px" class="cls_004"><span class="cls_004">When defining multiple named styles, it is common to reuse some of them in others. For</span></div>
<div style="position:absolute;left:5.00px;top:249.75px" class="cls_004"><span class="cls_004">example, if we have a default style for the </span><span class="cls_007">TextBox</span><span class="cls_004"> control, we can base other style</span></div>
<div style="position:absolute;left:5.00px;top:267.75px" class="cls_004"><span class="cls_004">variations on it. Let's see some XAML examples.</span></div>
<div style="position:absolute;left:52.98px;top:291.00px" class="cls_007"><span class="cls_007"><Style x:Key="TextBoxStyle" TargetType="{x:Type TextBox}"></span></div>
<div style="position:absolute;left:67.97px;top:304.50px" class="cls_007"><span class="cls_007"><Setter Property="SnapsToDevicePixels" Value="True" /></span></div>
<div style="position:absolute;left:67.97px;top:318.00px" class="cls_007"><span class="cls_007"><Setter Property="Margin" Value="0,0,0,5" /></span></div>
<div style="position:absolute;left:67.97px;top:331.50px" class="cls_007"><span class="cls_007"><Setter Property="Padding" Value="1.5,2" /></span></div>
<div style="position:absolute;left:67.97px;top:345.00px" class="cls_007"><span class="cls_007"><Setter Property="MinHeight" Value="25" /></span></div>
<div style="position:absolute;left:67.97px;top:358.50px" class="cls_007"><span class="cls_007"><Setter Property="TextWrapping" Value="Wrap" /></span></div>
<div style="position:absolute;left:52.98px;top:385.50px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:52.98px;top:399.00px" class="cls_007"><span class="cls_007"><Style x:Key="Max2LineTextBoxStyle" TargetType="{x:Type TextBox}"</span></div>
<div style="position:absolute;left:67.97px;top:412.50px" class="cls_007"><span class="cls_007">BasedOn="{StaticResource TextBoxStyle}"></span></div>
<div style="position:absolute;left:67.97px;top:426.00px" class="cls_007"><span class="cls_007"><Setter Property="MaxHeight" Value="44" /></span></div>
<div style="position:absolute;left:67.97px;top:439.50px" class="cls_007"><span class="cls_007"><Setter Property="VerticalScrollBarVisibility" Value="Auto" /></span></div>
<div style="position:absolute;left:67.97px;top:453.00px" class="cls_007"><span class="cls_007"><Setter Property="ToolTip"</span></div>
<div style="position:absolute;left:82.97px;top:466.50px" class="cls_007"><span class="cls_007">Value="{Binding Text, RelativeSource={RelativeSource Self}}" /></span></div>
<div style="position:absolute;left:52.98px;top:480.00px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:52.98px;top:493.50px" class="cls_007"><span class="cls_007"><Style x:Key="Max3LineTextBoxStyle" TargetType="{x:Type TextBox}"</span></div>
<div style="position:absolute;left:67.97px;top:507.00px" class="cls_007"><span class="cls_007">BasedOn="{StaticResource Max2LineTextBoxStyle}"></span></div>
<div style="position:absolute;left:67.97px;top:520.50px" class="cls_007"><span class="cls_007"><Setter Property="MaxHeight" Value="64" /></span></div>
<div style="position:absolute;left:52.98px;top:534.00px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:52.98px;top:547.50px" class="cls_007"><span class="cls_007"><Style x:Key="ReadOnlyTextBoxStyle" TargetType="{x:Type TextBox}"</span></div>
<div style="position:absolute;left:67.97px;top:561.00px" class="cls_007"><span class="cls_007">BasedOn="{StaticResource TextBoxStyle}"></span></div>
<div style="position:absolute;left:67.97px;top:574.50px" class="cls_007"><span class="cls_007"><Setter Property="Background" Value="{StaticResource</span></div>
<div style="position:absolute;left:52.98px;top:588.00px" class="cls_007"><span class="cls_007">ReadOnlyBrush}" /></span></div>
<div style="position:absolute;left:67.97px;top:601.50px" class="cls_007"><span class="cls_007"><Setter Property="IsReadOnly" Value="True" /></span></div>
<div style="position:absolute;left:67.97px;top:615.00px" class="cls_007"><span class="cls_007"><Setter Property="Cursor" Value="Arrow" /></span></div>
<div style="position:absolute;left:52.98px;top:628.50px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:5.00px;top:648.75px" class="cls_004"><span class="cls_004">Here, the simplified </span><span class="cls_007">TextBoxStyle</span><span class="cls_004"> style defines the majority of the properties for all </span><span class="cls_007">TextBox</span></div>
<div style="position:absolute;left:5.00px;top:666.75px" class="cls_004"><span class="cls_004">controls. The </span><span class="cls_007">Max2LineTextBoxStyle</span><span class="cls_004"> style inherits all of the property settings from this style</span></div>
<div style="position:absolute;left:5.00px;top:684.75px" class="cls_004"><span class="cls_004">and sets a few more that ensure that the vertical scrollbar can appear when required and</span></div>
<div style="position:absolute;left:5.00px;top:702.75px" class="cls_004"><span class="cls_004">enforce a maximum height for the control.</span></div>
<div style="position:absolute;left:5.00px;top:720.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">Max3LineTextBoxStyle</span><span class="cls_004"> style extends the </span><span class="cls_007">Max2LineTextBoxStyle</span><span class="cls_004"> style and so, inherits</span></div>
<div style="position:absolute;left:5.00px;top:738.75px" class="cls_004"><span class="cls_004">all of its property settings, as well as those of the </span><span class="cls_007">TextBoxStyle</span><span class="cls_004"> style. It overrides the</span></div>
<div style="position:absolute;left:5.00px;top:756.75px" class="cls_007"><span class="cls_007">MaxHeight</span><span class="cls_004"> property that was set in the previous style. The </span><span class="cls_007">ReadOnlyTextBoxStyle</span><span class="cls_004"> style also</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:217342px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background273.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">extends the </span><span class="cls_007">TextBoxStyle</span><span class="cls_004"> style and sets properties to ensure that the control is read-only.</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">Defining styles in this way ensures that controls in each View will remain consistent.</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">As well as defining default styles for our application controls, it is often also a good idea to</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">provide default data template resources for each data model in the application. In a similar</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">way to the controls, predefining these data templates can result in improved consistency.</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">We can also define a number of named templates to override the default ones with and use</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">in different scenarios.</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">If there are a large number of data models in an application, it can be helpful to also</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">declare their data templates in a separate resource file and merge it with the application</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">resources in the </span><span class="cls_007">App.xaml</span><span class="cls_004"> file, like the default control templates. It is therefore not unusual</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">to see multiple resource files being merged in the application resources file.</span></div>
<div style="position:absolute;left:5.00px;top:201.01px" class="cls_011"><span class="cls_011">Using professional icons</span></div>
<div style="position:absolute;left:5.00px;top:231.00px" class="cls_004"><span class="cls_004">One thing that can often be underestimated when developing applications is the overall</span></div>
<div style="position:absolute;left:5.00px;top:249.00px" class="cls_004"><span class="cls_004">impact that a consistent set of decent icons can have. Using miss-matched icons that have</span></div>
<div style="position:absolute;left:5.00px;top:267.00px" class="cls_004"><span class="cls_004">been sourced from a number of different places can really make an otherwise professional</span></div>
<div style="position:absolute;left:5.00px;top:285.00px" class="cls_004"><span class="cls_004">looking application look far less professional.</span></div>
<div style="position:absolute;left:5.00px;top:303.00px" class="cls_004"><span class="cls_004">If you or your company cannot afford to, or will not for any other reason buy a set of</span></div>
<div style="position:absolute;left:5.00px;top:321.00px" class="cls_004"><span class="cls_004">custom icons, all is not lost. Visual Studio has long since offered sets of professional icons</span></div>
<div style="position:absolute;left:5.00px;top:339.00px" class="cls_004"><span class="cls_004">in a number of different formats, that we can utilize in our applications free of charge. These</span></div>
<div style="position:absolute;left:5.00px;top:357.00px" class="cls_004"><span class="cls_004">are the actual icons that are used in Visual Studio, Office and other Microsoft applications,</span></div>
<div style="position:absolute;left:5.00px;top:375.00px" class="cls_004"><span class="cls_004">so many users will already be familiar with them.</span></div>
<div style="position:absolute;left:5.00px;top:393.00px" class="cls_004"><span class="cls_004">In older versions of Visual Studio, such as the 2010, or even 2008 versions, the provided</span></div>
<div style="position:absolute;left:5.00px;top:411.00px" class="cls_004"><span class="cls_004">image library was installed with the application and could be found at one of the following</span></div>
<div style="position:absolute;left:5.00px;top:429.00px" class="cls_004"><span class="cls_004">paths:</span></div>
<div style="position:absolute;left:34.99px;top:450.00px" class="cls_007"><span class="cls_007">C:\Program Files\Microsoft Visual Studio 9.0\Common7\VS2008ImageLibrary\1033</span></div>
<div style="position:absolute;left:34.99px;top:468.00px" class="cls_007"><span class="cls_007">C:\Program Files\Microsoft Visual Studio</span></div>
<div style="position:absolute;left:34.99px;top:486.00px" class="cls_007"><span class="cls_007">10.0\Common7\VS2010ImageLibrary\1033</span></div>
<div style="position:absolute;left:5.00px;top:501.00px" class="cls_004"><span class="cls_004">Note that on a 64 bit machine, this path would change to the following:</span></div>
<div style="position:absolute;left:34.99px;top:522.00px" class="cls_007"><span class="cls_007">C:\Program Files (x86)\Microsoft Visual Studio</span></div>
<div style="position:absolute;left:34.99px;top:540.00px" class="cls_007"><span class="cls_007">10.0\Common7\VS2010ImageLibrary\1033</span></div>
<div style="position:absolute;left:5.00px;top:555.00px" class="cls_004"><span class="cls_004">However, Microsoft changed how the image library could be accessed in newer versions of</span></div>
<div style="position:absolute;left:5.00px;top:573.00px" class="cls_004"><span class="cls_004">Visual Studio, from the 2012 version onwards. In these later versions, the image library was</span></div>
<div style="position:absolute;left:5.00px;top:591.00px" class="cls_004"><span class="cls_004">no longer included in the installation of Visual Studio. Instead, we have to manually</span></div>
<div style="position:absolute;left:5.00px;top:609.00px" class="cls_004"><span class="cls_004">download it from the </span><span class="cls_005">Microsoft Developer Network</span><span class="cls_004"> (</span><span class="cls_005">MSDN</span><span class="cls_004">) website.</span></div>
<div style="position:absolute;left:5.00px;top:627.75px" class="cls_004"><span class="cls_004">We can find them all by navigating to the MSDN website and searching for </span><span class="cls_007">Visual Studio</span></div>
<div style="position:absolute;left:5.00px;top:645.75px" class="cls_007"><span class="cls_007">Image Library</span><span class="cls_004">. All versions of these icon sets can be accessed from there, although the</span></div>
<div style="position:absolute;left:5.00px;top:663.75px" class="cls_004"><span class="cls_004">newer versions also contain the older versions, so downloading the latest set is normally the</span></div>
<div style="position:absolute;left:5.00px;top:681.75px" class="cls_004"><span class="cls_004">best option.</span></div>
<div style="position:absolute;left:5.00px;top:699.75px" class="cls_004"><span class="cls_004">The newer icon sets also contain searchable Adobe Reader files that list the contents of the</span></div>
<div style="position:absolute;left:5.00px;top:717.75px" class="cls_004"><span class="cls_004">icon sets and provide links to the relevant folders of each of the icons. Most of the icons are</span></div>
<div style="position:absolute;left:5.00px;top:735.75px" class="cls_004"><span class="cls_004">also included in multiple sizes and so the newer libraries are much larger than the previous</span></div>
<div style="position:absolute;left:5.00px;top:753.75px" class="cls_004"><span class="cls_004">ones. A few examples of the 2010 icons can be seen in the following image:</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:218144px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background274.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:77.25px" class="cls_004"><span class="cls_004">The following image shows the latest flat style icons for comparison:</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:218946px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background275.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_008"><span class="cls_008">Layering visuals</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">So far, we've just looked at simple redefinitions of the standard controls, by altering shapes,</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">sizes, borders and other common properties. However, we can do much more than that</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">with WPF. Before continuing with this section, it is important to know that the more visuals</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">that each control is comprised of, the longer it will take to render them and so, this can</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">negatively affect performance.</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">As such, it's important not to overdo the visual aspect of our controls if our application will</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">be run on slow, old computers. Conversely, if we know that our end users will have plenty of</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">RAM and/or graphics cards, then we can go the extra distance and develop visually</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">stunning controls. Let's look at some techniques that we can use to improve the look of our</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">controls.</span></div>
<div style="position:absolute;left:5.00px;top:219.01px" class="cls_011"><span class="cls_011">Throwing shadows</span></div>
<div style="position:absolute;left:5.00px;top:249.00px" class="cls_004"><span class="cls_004">One of the easiest ways to make our UI elements pop out of the screen is to add a shadow</span></div>
<div style="position:absolute;left:5.00px;top:267.00px" class="cls_004"><span class="cls_004">to them. Each control has an </span><span class="cls_007">Effect</span><span class="cls_004"> property that is inherited from the </span><span class="cls_007">UIElement</span><span class="cls_004"> class.</span></div>
<div style="position:absolute;left:5.00px;top:285.00px" class="cls_004"><span class="cls_004">We can set an object of type </span><span class="cls_007">DropShadowEffect</span><span class="cls_004"> to this property to add a shadow to our</span></div>
<div style="position:absolute;left:5.00px;top:303.00px" class="cls_004"><span class="cls_004">controls.</span></div>
<div style="position:absolute;left:5.00px;top:321.00px" class="cls_004"><span class="cls_004">However, we must be conservative with the settings that we use on the </span><span class="cls_007">DropShadowEffect</span></div>
<div style="position:absolute;left:5.00px;top:339.00px" class="cls_004"><span class="cls_004">element, because this effect can be easily overdone. We also do not want to apply this</span></div>
<div style="position:absolute;left:5.00px;top:357.00px" class="cls_004"><span class="cls_004">effect to every control, as that would spoil the overall effect. It is most useful when set on a</span></div>
<div style="position:absolute;left:5.00px;top:375.00px" class="cls_004"><span class="cls_004">panel that contains other controls, or on a border that surrounds such a panel. Let's see a</span></div>
<div style="position:absolute;left:5.00px;top:393.00px" class="cls_004"><span class="cls_004">simple example of applying this effect.</span></div>
<div style="position:absolute;left:52.98px;top:416.25px" class="cls_007"><span class="cls_007"><Button Content="Click Me" Width="140" Height="34" FontSize="18"></span></div>
<div style="position:absolute;left:67.97px;top:429.75px" class="cls_007"><span class="cls_007"><Button.Effect></span></div>
<div style="position:absolute;left:82.97px;top:443.25px" class="cls_007"><span class="cls_007"><DropShadowEffect Color="Black" ShadowDepth="6" BlurRadius="6"</span></div>
<div style="position:absolute;left:97.96px;top:456.75px" class="cls_007"><span class="cls_007">Direction="270" Opacity="0.5" /></span></div>
<div style="position:absolute;left:67.97px;top:470.25px" class="cls_007"><span class="cls_007"></Button.Effect></span></div>
<div style="position:absolute;left:52.98px;top:483.75px" class="cls_007"><span class="cls_007"></Button></span></div>
<div style="position:absolute;left:5.00px;top:516.75px" class="cls_004"><span class="cls_004">Let's see what the output of this code looks like:</span></div>
<div style="position:absolute;left:5.00px;top:606.75px" class="cls_004"><span class="cls_004">In this example, we have a standard button with a </span><span class="cls_007">DropShadowEffect</span><span class="cls_004"> element that is set as</span></div>
<div style="position:absolute;left:5.00px;top:624.75px" class="cls_004"><span class="cls_004">its </span><span class="cls_007">Effect</span><span class="cls_004"> property. As we'll see later in this chapter, the </span><span class="cls_007">DropShadowEffect</span><span class="cls_004"> class has a</span></div>
<div style="position:absolute;left:5.00px;top:642.75px" class="cls_004"><span class="cls_004">number of uses, but its primary use is to create shadow effects.</span></div>
<div style="position:absolute;left:5.00px;top:660.75px" class="cls_004"><span class="cls_004">When using this element for shadow effects, we generally want to set its </span><span class="cls_007">Color</span><span class="cls_004"> property to</span></div>
<div style="position:absolute;left:5.00px;top:678.75px" class="cls_004"><span class="cls_004">black and its </span><span class="cls_007">Opacity</span><span class="cls_004"> property to a value that is at least semi-transparent for best, or most</span></div>
<div style="position:absolute;left:5.00px;top:696.75px" class="cls_004"><span class="cls_004">realistic, results. The </span><span class="cls_007">ShadowDepth</span><span class="cls_004"> property dictates how far from the element the shadow</span></div>
<div style="position:absolute;left:5.00px;top:714.75px" class="cls_004"><span class="cls_004">should fall. Along with the </span><span class="cls_007">BlurRadius</span><span class="cls_004"> property, this property is used to add a sense of</span></div>
<div style="position:absolute;left:5.00px;top:732.75px" class="cls_004"><span class="cls_004">height to the element.</span></div>
<div style="position:absolute;left:5.00px;top:750.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">BlurRadius</span><span class="cls_004"> property spreads out the shadow area, while also making it less dense.</span></div>
<div style="position:absolute;left:5.00px;top:768.75px" class="cls_004"><span class="cls_004">Like the </span><span class="cls_007">ShadowDepth</span><span class="cls_004"> property, this property has a default value of five. The </span><span class="cls_007">Direction</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:219748px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background276.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">property specifies which direction the shadow should fall in, with a value of zero degrees</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">making the shadow fall to the right and increasing values moving the shadow angle anti-</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">clockwise.</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">Note that a value of </span><span class="cls_007">270</span><span class="cls_004"> makes the shadow fall directly below the applied control and is</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">often most suitable for use in business applications. Using this angle results in what appears</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">to be an element that is hovering slightly above, or in front of, the screen, with a light source</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">coming from above, which is the most natural direction for light to come from.</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">In contrast to this, an angle of </span><span class="cls_007">45</span><span class="cls_004"> degrees for example, would place the shadow to the top</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">right of the element and this would have the effect of telling the brain that there is a light</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">source to the bottom left. However, this particular effect is unnatural looking and can detract</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">from, rather than add to the styling of an application.</span></div>
<div style="position:absolute;left:5.00px;top:201.01px" class="cls_011"><span class="cls_011">Declaring multiple borders</span></div>
<div style="position:absolute;left:5.00px;top:231.00px" class="cls_004"><span class="cls_004">One simple technique that we can use to make our controls stand out is to use multiple</span></div>
<div style="position:absolute;left:5.00px;top:249.00px" class="cls_007"><span class="cls_007">Border</span><span class="cls_004"> elements for each control. By declaring one or more borders within an outer border,</span></div>
<div style="position:absolute;left:5.00px;top:267.00px" class="cls_004"><span class="cls_004">we can give our controls that professional look. We'll see how we can animate these</span></div>
<div style="position:absolute;left:5.00px;top:285.00px" class="cls_004"><span class="cls_004">borders differently when the user's mouse cursor is over the button later, but for now, let's</span></div>
<div style="position:absolute;left:5.00px;top:303.00px" class="cls_004"><span class="cls_004">see how we can create this effect.</span></div>
<div style="position:absolute;left:52.98px;top:326.25px" class="cls_007"><span class="cls_007"><Grid Width="160" Height="68"></span></div>
<div style="position:absolute;left:67.97px;top:339.75px" class="cls_007"><span class="cls_007"><Grid.Background></span></div>
<div style="position:absolute;left:82.97px;top:353.25px" class="cls_007"><span class="cls_007"><LinearGradientBrush StartPoint="0,0" EndPoint="1,1"></span></div>
<div style="position:absolute;left:97.96px;top:366.75px" class="cls_007"><span class="cls_007"><GradientStop Color="Red" /></span></div>
<div style="position:absolute;left:97.96px;top:380.25px" class="cls_007"><span class="cls_007"><GradientStop Color="Yellow" Offset="1" /></span></div>
<div style="position:absolute;left:82.97px;top:393.75px" class="cls_007"><span class="cls_007"></LinearGradientBrush></span></div>
<div style="position:absolute;left:67.97px;top:407.25px" class="cls_007"><span class="cls_007"></Grid.Background></span></div>
<div style="position:absolute;left:67.97px;top:420.75px" class="cls_007"><span class="cls_007"><Button Content="Click Me" Width="120" Height="28" FontSize="14"</span></div>
<div style="position:absolute;left:82.97px;top:434.25px" class="cls_007"><span class="cls_007">Margin="20"></span></div>
<div style="position:absolute;left:82.97px;top:447.75px" class="cls_007"><span class="cls_007"><Button.Template></span></div>
<div style="position:absolute;left:97.96px;top:461.25px" class="cls_007"><span class="cls_007"><ControlTemplate TargetType="{x:Type Button}"></span></div>
<div style="position:absolute;left:112.96px;top:474.75px" class="cls_007"><span class="cls_007"><Border BorderBrush="Black" BorderThickness="1"</span></div>
<div style="position:absolute;left:127.95px;top:488.25px" class="cls_007"><span class="cls_007">Background="#7FFFFFFF" Padding="1" CornerRadius="5"</span></div>
<div style="position:absolute;left:127.95px;top:501.75px" class="cls_007"><span class="cls_007">SnapsToDevicePixels="True"></span></div>
<div style="position:absolute;left:127.95px;top:515.25px" class="cls_007"><span class="cls_007"><Border BorderBrush="#7F000000" BorderThickness="1"</span></div>
<div style="position:absolute;left:142.94px;top:528.75px" class="cls_007"><span class="cls_007">Background="White" CornerRadius="3.5"</span></div>
<div style="position:absolute;left:142.94px;top:542.25px" class="cls_007"><span class="cls_007">SnapsToDevicePixels="True"></span></div>
<div style="position:absolute;left:142.94px;top:555.75px" class="cls_007"><span class="cls_007"><ContentPresenter HorizontalAlignment="Center"</span></div>
<div style="position:absolute;left:157.94px;top:569.25px" class="cls_007"><span class="cls_007">VerticalAlignment="Center" /></span></div>
<div style="position:absolute;left:127.95px;top:582.75px" class="cls_007"><span class="cls_007"></Border></span></div>
<div style="position:absolute;left:112.96px;top:596.25px" class="cls_007"><span class="cls_007"></Border></span></div>
<div style="position:absolute;left:97.96px;top:609.75px" class="cls_007"><span class="cls_007"></ControlTemplate></span></div>
<div style="position:absolute;left:82.97px;top:623.25px" class="cls_007"><span class="cls_007"></Button.Template></span></div>
<div style="position:absolute;left:67.97px;top:636.75px" class="cls_007"><span class="cls_007"></Button></span></div>
<div style="position:absolute;left:52.98px;top:650.25px" class="cls_007"><span class="cls_007"></Grid></span></div>
<div style="position:absolute;left:5.00px;top:683.25px" class="cls_004"><span class="cls_004">In this example, we have declared a simple </span><span class="cls_007">ControlTemplate</span><span class="cls_004"> element for our </span><span class="cls_007">Button</span><span class="cls_004"> control</span></div>
<div style="position:absolute;left:5.00px;top:701.25px" class="cls_004"><span class="cls_004">to demonstrate the double border technique. Note that we would typically declare this</span></div>
<div style="position:absolute;left:5.00px;top:719.25px" class="cls_004"><span class="cls_004">template in the </span><span class="cls_007">Application.Resources</span><span class="cls_004"> section of the </span><span class="cls_007">App.xaml</span><span class="cls_004"> file, so that it could be</span></div>
<div style="position:absolute;left:5.00px;top:737.25px" class="cls_004"><span class="cls_004">reused, but we have declared it locally to save space here.</span></div>
<div style="position:absolute;left:5.00px;top:755.25px" class="cls_004"><span class="cls_004">Note that we need to adjust the corner radius of the inner border to accurately fit within the</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:220550px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background277.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">outer border. If we had used the same size for both, they would not have correctly fit</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">together. Also, we have set the </span><span class="cls_007">SnapsToDevicePixels</span><span class="cls_004"> property to </span><span class="cls_007">true</span><span class="cls_004"> on the two borders</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">to ensure that they are not blurred by anti-aliasing artefacts.</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">One further point to note is that we have used </span><span class="cls_007">#7FFFFFFF</span><span class="cls_004"> as the value for the background of</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">the outer border and the border brush of the inner border. The alpha channel in this value is</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">set to </span><span class="cls_007">7F</span><span class="cls_004">, which equates to an opacity value of </span><span class="cls_007">0.5</span><span class="cls_004">. This means that these elements will be</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">partly transparent and so the colors from the background will partly show through the</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">border edges.</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">We added our button into a </span><span class="cls_007">Grid</span><span class="cls_004"> panel and set a </span><span class="cls_007">LinearGradientBrush</span><span class="cls_004"> object as its</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">background to demonstrate this semi-transparent effect. When rendered, our background</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">gradient and button will look like the following image:</span></div>
<div style="position:absolute;left:5.00px;top:279.01px" class="cls_011"><span class="cls_011">Reusing composite visuals</span></div>
<div style="position:absolute;left:5.00px;top:309.00px" class="cls_004"><span class="cls_004">The next technique involves defining a particular motif that will be rendered in the</span></div>
<div style="position:absolute;left:5.00px;top:327.00px" class="cls_004"><span class="cls_004">background of our controls. This could be all or part of a company logo, a particular shape,</span></div>
<div style="position:absolute;left:5.00px;top:345.00px" class="cls_004"><span class="cls_004">or even just a simple, well-placed curve. This will form the bottom most level of our control</span></div>
<div style="position:absolute;left:5.00px;top:363.00px" class="cls_004"><span class="cls_004">visuals, and can have additional levels of visuals on top. Let's take a look at one way that</span></div>
<div style="position:absolute;left:5.00px;top:381.00px" class="cls_004"><span class="cls_004">we could implement such a design, starting with defining some resources.</span></div>
<div style="position:absolute;left:52.98px;top:404.25px" class="cls_007"><span class="cls_007"><RadialGradientBrush x:Key="LayeredButtonBackgroundBrush"</span></div>
<div style="position:absolute;left:52.98px;top:417.75px" class="cls_007"><span class="cls_007">RadiusX="1.85"</span></div>
<div style="position:absolute;left:67.97px;top:431.25px" class="cls_007"><span class="cls_007">RadiusY="0.796" Center="1.018,-0.115" GradientOrigin="0.65,-</span></div>
<div style="position:absolute;left:52.98px;top:444.75px" class="cls_007"><span class="cls_007">0.139"></span></div>
<div style="position:absolute;left:67.97px;top:458.25px" class="cls_007"><span class="cls_007"><GradientStop Color="#FFCACACD" /></span></div>
<div style="position:absolute;left:67.97px;top:471.75px" class="cls_007"><span class="cls_007"><GradientStop Color="#FF3B3D42" Offset="1" /></span></div>
<div style="position:absolute;left:52.98px;top:485.25px" class="cls_007"><span class="cls_007"></RadialGradientBrush></span></div>
<div style="position:absolute;left:52.98px;top:498.75px" class="cls_007"><span class="cls_007"><LinearGradientBrush x:Key="LayeredButtonCurveBrush"</span></div>
<div style="position:absolute;left:52.98px;top:512.25px" class="cls_007"><span class="cls_007">StartPoint="0,0"</span></div>
<div style="position:absolute;left:67.97px;top:525.75px" class="cls_007"><span class="cls_007">EndPoint="1,1"></span></div>
<div style="position:absolute;left:67.97px;top:539.25px" class="cls_007"><span class="cls_007"><GradientStop Color="#FF747475" Offset="0" /></span></div>
<div style="position:absolute;left:67.97px;top:552.75px" class="cls_007"><span class="cls_007"><GradientStop Color="#FF3B3D42" Offset="1" /></span></div>
<div style="position:absolute;left:52.98px;top:566.25px" class="cls_007"><span class="cls_007"></LinearGradientBrush></span></div>
<div style="position:absolute;left:52.98px;top:579.75px" class="cls_007"><span class="cls_007"><Grid x:Key="LayeredButtonBackgroundElements"></span></div>
<div style="position:absolute;left:67.97px;top:593.25px" class="cls_007"><span class="cls_007"><Rectangle Fill="{StaticResource LayeredButtonBackgroundBrush}"</span></div>
<div style="position:absolute;left:52.98px;top:606.75px" class="cls_007"><span class="cls_007">/></span></div>
<div style="position:absolute;left:67.97px;top:620.25px" class="cls_007"><span class="cls_007"><Path StrokeThickness="0"</span></div>
<div style="position:absolute;left:82.97px;top:633.75px" class="cls_007"><span class="cls_007">Fill="{StaticResource LayeredButtonCurveBrush}"></span></div>
<div style="position:absolute;left:82.97px;top:647.25px" class="cls_007"><span class="cls_007"><Path.Data></span></div>
<div style="position:absolute;left:97.96px;top:660.75px" class="cls_007"><span class="cls_007"><CombinedGeometry GeometryCombineMode="Intersect"></span></div>
<div style="position:absolute;left:112.96px;top:674.25px" class="cls_007"><span class="cls_007"><CombinedGeometry.Geometry1></span></div>
<div style="position:absolute;left:127.95px;top:687.75px" class="cls_007"><span class="cls_007"><EllipseGeometry Center="-20,50.7" RadiusX="185"</span></div>
<div style="position:absolute;left:52.98px;top:701.25px" class="cls_007"><span class="cls_007">RadiusY="46" /></span></div>
<div style="position:absolute;left:112.96px;top:714.75px" class="cls_007"><span class="cls_007"></CombinedGeometry.Geometry1></span></div>
<div style="position:absolute;left:112.96px;top:728.25px" class="cls_007"><span class="cls_007"><CombinedGeometry.Geometry2></span></div>
<div style="position:absolute;left:127.95px;top:741.75px" class="cls_007"><span class="cls_007"><RectangleGeometry Rect="0,0,106,24" /></span></div>
<div style="position:absolute;left:112.96px;top:755.25px" class="cls_007"><span class="cls_007"></CombinedGeometry.Geometry2></span></div>
<div style="position:absolute;left:97.96px;top:768.75px" class="cls_007"><span class="cls_007"></CombinedGeometry></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:221352px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background278.jpg" width=612 height=792></div>
<div style="position:absolute;left:82.97px;top:3.00px" class="cls_007"><span class="cls_007"></Path.Data></span></div>
<div style="position:absolute;left:67.97px;top:16.50px" class="cls_007"><span class="cls_007"></Path></span></div>
<div style="position:absolute;left:52.98px;top:30.00px" class="cls_007"><span class="cls_007"></Grid></span></div>
<div style="position:absolute;left:52.98px;top:43.50px" class="cls_007"><span class="cls_007"><VisualBrush x:Key="LayeredButtonBackground"</span></div>
<div style="position:absolute;left:67.97px;top:57.00px" class="cls_007"><span class="cls_007">Visual="{StaticResource LayeredButtonBackgroundElements}" /></span></div>
<div style="position:absolute;left:5.00px;top:77.25px" class="cls_004"><span class="cls_004">Once we have added these resources into the </span><span class="cls_007">Application.Resources</span><span class="cls_004"> section in the</span></div>
<div style="position:absolute;left:5.00px;top:95.25px" class="cls_007"><span class="cls_007">App.xaml</span><span class="cls_004"> file, we can use them through the </span><span class="cls_007">VisualBrush</span><span class="cls_004"> element, like this:</span></div>
<div style="position:absolute;left:52.98px;top:118.50px" class="cls_007"><span class="cls_007"><Button Background="{StaticResource LayeredButtonBackground}"</span></div>
<div style="position:absolute;left:52.98px;top:132.00px" class="cls_007"><span class="cls_007">Width="200"</span></div>
<div style="position:absolute;left:67.97px;top:145.50px" class="cls_007"><span class="cls_007">Height="40" SnapsToDevicePixels="True" /></span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">This will render the gradients in the button background, like this.</span></div>
<div style="position:absolute;left:5.00px;top:260.25px" class="cls_004"><span class="cls_004">There are a few elements to this design, so let's look at each one individually. We started</span></div>
<div style="position:absolute;left:5.00px;top:278.25px" class="cls_004"><span class="cls_004">by declaring a </span><span class="cls_007">RadialGradientBrush</span><span class="cls_004"> element with the key </span><span class="cls_007">LayeredButtonBackgroundBrush</span></div>
<div style="position:absolute;left:5.00px;top:296.25px" class="cls_004"><span class="cls_004">and a </span><span class="cls_007">LinearGradientBrush</span><span class="cls_004"> with a key of </span><span class="cls_007">LayeredButtonCurveBrush</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:314.25px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">RadiusX</span><span class="cls_004"> and </span><span class="cls_007">Radius</span><span class="cls_004"> </span><span class="cls_007">Y</span><span class="cls_004"> properties of the </span><span class="cls_007">RadialGradientBrush</span><span class="cls_004"> element specify the </span><span class="cls_007">X</span></div>
<div style="position:absolute;left:5.00px;top:332.25px" class="cls_004"><span class="cls_004">and </span><span class="cls_007">Y</span><span class="cls_004"> radii of the outermost ellipse that encompasses the radial gradient, while the </span><span class="cls_007">Center</span></div>
<div style="position:absolute;left:5.00px;top:350.25px" class="cls_004"><span class="cls_004">and </span><span class="cls_007">GradientOrigin</span><span class="cls_004"> properties dictate the center and focal point of the radial gradient and</span></div>
<div style="position:absolute;left:5.00px;top:368.25px" class="cls_004"><span class="cls_004">enable us to position it precisely within our rectangle.</span></div>
<div style="position:absolute;left:5.00px;top:386.25px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">LinearGradientBrush</span><span class="cls_004"> element has a </span><span class="cls_007">StartPoint</span><span class="cls_004"> value of </span><span class="cls_007">0, 0</span><span class="cls_004"> and an </span><span class="cls_007">EndPoint</span><span class="cls_004"> value</span></div>
<div style="position:absolute;left:5.00px;top:404.25px" class="cls_004"><span class="cls_004">of </span><span class="cls_007">1, 1</span><span class="cls_004">, which results in a diagonal gradient. With this particular design, the idea is to have</span></div>
<div style="position:absolute;left:5.00px;top:422.25px" class="cls_004"><span class="cls_004">a sharp contrast between the two gradients at the center and to somewhat blend them</span></div>
<div style="position:absolute;left:5.00px;top:440.25px" class="cls_004"><span class="cls_004">together at the edges.</span></div>
<div style="position:absolute;left:5.00px;top:458.25px" class="cls_004"><span class="cls_004">Next, we declare a </span><span class="cls_007">Grid</span><span class="cls_004"> panel with the key </span><span class="cls_007">LayeredButtonBackgroundElements</span><span class="cls_004">, that</span></div>
<div style="position:absolute;left:5.00px;top:476.25px" class="cls_004"><span class="cls_004">contains a </span><span class="cls_007">Rectangle</span><span class="cls_004"> and a </span><span class="cls_007">Path</span><span class="cls_004"> element. The rectangle is stretched to fill the panel by</span></div>
<div style="position:absolute;left:5.00px;top:494.25px" class="cls_004"><span class="cls_004">default and is painted with the </span><span class="cls_007">LayeredButtonBackgroundBrush</span><span class="cls_004"> resource. The </span><span class="cls_007">Path</span><span class="cls_004"> element</span></div>
<div style="position:absolute;left:5.00px;top:512.25px" class="cls_004"><span class="cls_004">is painted with the </span><span class="cls_007">LayeredButtonCurveBrush</span><span class="cls_004"> resource.</span></div>
<div style="position:absolute;left:5.00px;top:530.25px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">Data</span><span class="cls_004"> property of the </span><span class="cls_007">Path</span><span class="cls_004"> object is where we define the shape of the path. There are a</span></div>
<div style="position:absolute;left:5.00px;top:548.25px" class="cls_004"><span class="cls_004">number of ways that we can specify the path data, but in this example, we use a</span></div>
<div style="position:absolute;left:5.00px;top:566.25px" class="cls_007"><span class="cls_007">CombinedGeometry</span><span class="cls_004"> element with a </span><span class="cls_007">GeometryCombineMode</span><span class="cls_004"> value of </span><span class="cls_007">Intersect</span><span class="cls_004">, which outputs</span></div>
<div style="position:absolute;left:5.00px;top:584.25px" class="cls_004"><span class="cls_004">a single shape that represents the intersection of the two specified geometry shapes.</span></div>
<div style="position:absolute;left:5.00px;top:602.25px" class="cls_004"><span class="cls_004">Inside the </span><span class="cls_007">CombinedGeometry</span><span class="cls_004"> element, we have the </span><span class="cls_007">Geometry1</span><span class="cls_004"> and </span><span class="cls_007">Geometry</span><span class="cls_004"> </span><span class="cls_007">2</span><span class="cls_004"> properties,</span></div>
<div style="position:absolute;left:5.00px;top:620.25px" class="cls_004"><span class="cls_004">where we combine the two geometry shapes, according to the </span><span class="cls_007">Intersect</span><span class="cls_004"> mode specified</span></div>
<div style="position:absolute;left:5.00px;top:638.25px" class="cls_004"><span class="cls_004">by the </span><span class="cls_007">GeometryCombineMode</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:5.00px;top:656.25px" class="cls_004"><span class="cls_004">Our first shape defines the curve in our design and comes from an </span><span class="cls_007">EllipseGeometry</span></div>
<div style="position:absolute;left:5.00px;top:674.25px" class="cls_004"><span class="cls_004">element, using the </span><span class="cls_007">Center</span><span class="cls_004"> property to position the ellipse and the </span><span class="cls_007">RadiusX</span><span class="cls_004"> and </span><span class="cls_007">RadiusY</span></div>
<div style="position:absolute;left:5.00px;top:692.25px" class="cls_004"><span class="cls_004">properties to shape it. The second shape is a rectangle that comes from a</span></div>
<div style="position:absolute;left:5.00px;top:710.25px" class="cls_007"><span class="cls_007">RectangleGeometry</span><span class="cls_004"> element and is defined by its </span><span class="cls_007">Rect</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:5.00px;top:728.25px" class="cls_004"><span class="cls_004">The intersection of these two shapes is the result of this path and approximately covers the</span></div>
<div style="position:absolute;left:5.00px;top:746.25px" class="cls_004"><span class="cls_004">bottom section of our overall shape, up to the curve. The partly obscured rectangle element</span></div>
<div style="position:absolute;left:5.00px;top:764.25px" class="cls_004"><span class="cls_004">behind completes the remainder of the overall shape.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:222154px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background279.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">Visual</span><span class="cls_004"> property of the </span><span class="cls_007">VisualBrush</span><span class="cls_004"> element with key </span><span class="cls_007">LayeredButtonBackground</span><span class="cls_004"> is set</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">to the </span><span class="cls_007">LayeredButtonBackgroundElements</span><span class="cls_004"> panel and so, any UI element that is painted with</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">this brush will now have this design imprinted on it. In our example, we manually specify the</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">reference to the visual brush to paint the </span><span class="cls_007">Button</span><span class="cls_004"> object's background.</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">However, setting the background in this way would require the developers that use our</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">application framework to do this each time they add a button. A better solution would be to</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">redesign the default button template, so that the visual brush is automatically applied to</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">each button. We'll see an example of this later in this chapter, when we pull together a</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">number of these techniques.</span></div>
<div style="position:absolute;left:5.00px;top:165.01px" class="cls_011"><span class="cls_011">Reflecting light</span></div>
<div style="position:absolute;left:5.00px;top:195.00px" class="cls_004"><span class="cls_004">Another technique involves adding a semi-opaque layer with a gradient that fades to</span></div>
<div style="position:absolute;left:5.00px;top:213.00px" class="cls_004"><span class="cls_004">transparency over the top of our controls to give the appearance of the reflection of a light</span></div>
<div style="position:absolute;left:5.00px;top:231.00px" class="cls_004"><span class="cls_004">source. This can easily be achieved using a simple </span><span class="cls_007">Border</span><span class="cls_004"> element and a</span></div>
<div style="position:absolute;left:5.00px;top:249.00px" class="cls_007"><span class="cls_007">LinearGradientBrush</span><span class="cls_004"> instance. Let's see how we can accomplish this:</span></div>
<div style="position:absolute;left:52.98px;top:272.25px" class="cls_007"><span class="cls_007"><Button Content="Click Me" Width="140" Height="34" FontSize="18"</span></div>
<div style="position:absolute;left:67.97px;top:285.75px" class="cls_007"><span class="cls_007">Foreground="White" Margin="20"></span></div>
<div style="position:absolute;left:67.97px;top:299.25px" class="cls_007"><span class="cls_007"><Button.Template></span></div>
<div style="position:absolute;left:82.97px;top:312.75px" class="cls_007"><span class="cls_007"><ControlTemplate TargetType="{x:Type Button}"></span></div>
<div style="position:absolute;left:97.96px;top:326.25px" class="cls_007"><span class="cls_007"><Border Background="#FF007767" CornerRadius="5"</span></div>
<div style="position:absolute;left:112.96px;top:339.75px" class="cls_007"><span class="cls_007">SnapsToDevicePixels="True"></span></div>
<div style="position:absolute;left:112.96px;top:353.25px" class="cls_007"><span class="cls_007"><Grid></span></div>
<div style="position:absolute;left:127.95px;top:366.75px" class="cls_007"><span class="cls_007"><Rectangle RadiusX="4" RadiusY="4" Margin="1,1,1,7"</span></div>
<div style="position:absolute;left:142.94px;top:380.25px" class="cls_007"><span class="cls_007">SnapsToDevicePixels="True"></span></div>
<div style="position:absolute;left:142.94px;top:393.75px" class="cls_007"><span class="cls_007"><Rectangle.Fill></span></div>
<div style="position:absolute;left:157.94px;top:407.25px" class="cls_007"><span class="cls_007"><LinearGradientBrush StartPoint="0,0" EndPoint="0,1"></span></div>
<div style="position:absolute;left:172.93px;top:420.75px" class="cls_007"><span class="cls_007"><GradientStop Color="#BFFFFFFF" /></span></div>
<div style="position:absolute;left:172.93px;top:434.25px" class="cls_007"><span class="cls_007"><GradientStop Color="#00FFFFFF" Offset="0.8" /></span></div>
<div style="position:absolute;left:157.94px;top:447.75px" class="cls_007"><span class="cls_007"></LinearGradientBrush></span></div>
<div style="position:absolute;left:142.94px;top:461.25px" class="cls_007"><span class="cls_007"></Rectangle.Fill></span></div>
<div style="position:absolute;left:127.95px;top:474.75px" class="cls_007"><span class="cls_007"></Rectangle></span></div>
<div style="position:absolute;left:127.95px;top:488.25px" class="cls_007"><span class="cls_007"><ContentPresenter HorizontalAlignment="Center"</span></div>
<div style="position:absolute;left:142.94px;top:501.75px" class="cls_007"><span class="cls_007">VerticalAlignment="Center" /></span></div>
<div style="position:absolute;left:112.96px;top:515.25px" class="cls_007"><span class="cls_007"></Grid></span></div>
<div style="position:absolute;left:97.96px;top:528.75px" class="cls_007"><span class="cls_007"></Border></span></div>
<div style="position:absolute;left:82.97px;top:542.25px" class="cls_007"><span class="cls_007"></ControlTemplate></span></div>
<div style="position:absolute;left:67.97px;top:555.75px" class="cls_007"><span class="cls_007"></Button.Template></span></div>
<div style="position:absolute;left:52.98px;top:569.25px" class="cls_007"><span class="cls_007"></Button></span></div>
<div style="position:absolute;left:5.00px;top:602.25px" class="cls_004"><span class="cls_004">When run, this example will produce a button that looks like this:</span></div>
<div style="position:absolute;left:5.00px;top:692.25px" class="cls_004"><span class="cls_004">Let's examine this example. We start by declaring the </span><span class="cls_007">Button</span><span class="cls_004"> element with a few style</span></div>
<div style="position:absolute;left:5.00px;top:710.25px" class="cls_004"><span class="cls_004">properties. Rather than defining a separate style or control template in a resources section</span></div>
<div style="position:absolute;left:5.00px;top:728.25px" class="cls_004"><span class="cls_004">as we would in a real world application, we again declare the template inline to save space</span></div>
<div style="position:absolute;left:5.00px;top:746.25px" class="cls_004"><span class="cls_004">here.</span></div>
<div style="position:absolute;left:5.00px;top:764.25px" class="cls_004"><span class="cls_004">In the control template, we first declare a </span><span class="cls_007">Border</span><span class="cls_004"> element with a jade green background</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:222956px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background280.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">and a </span><span class="cls_007">CornerRadius</span><span class="cls_004"> value of </span><span class="cls_007">5</span><span class="cls_004">. We again set the </span><span class="cls_007">SnapsToDevicePixels</span><span class="cls_004"> property to </span><span class="cls_007">true</span><span class="cls_004"> go</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">ensure that the edges remain sharp.</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">Inside the border, we define two elements within a </span><span class="cls_007">Grid</span><span class="cls_004"> panel. The first is the </span><span class="cls_007">Rectangle</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">element that produces the reflection effect and the second is the required</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_007"><span class="cls_007">ContentPresenter</span><span class="cls_004"> object. The rectangle uses a value of </span><span class="cls_007">4</span><span class="cls_004"> in the </span><span class="cls_007">RadiusX</span><span class="cls_004"> and </span><span class="cls_007">RadiusY</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">properties and sets the </span><span class="cls_007">Margin</span><span class="cls_004"> property appropriately to ensure that there is a tiny gap</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">around the edge of the reflection.</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">It also sets its </span><span class="cls_007">SnapsToDevicePixels</span><span class="cls_004"> property to true to ensure that this tiny gap is not</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">blurred. Note that the value for the bottom margin is </span><span class="cls_007">7</span><span class="cls_004">, because we do not want the</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">reflection effect to cover the bottom half of the button. The </span><span class="cls_007">Fill</span><span class="cls_004"> property is where the</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">reflection effect is actually created.</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">In the rectangle's </span><span class="cls_007">Fill</span><span class="cls_004"> property, we define a vertical </span><span class="cls_007">LinearGradientBrush</span><span class="cls_004"> element by</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">setting both of the </span><span class="cls_007">X</span><span class="cls_004"> values of the </span><span class="cls_007">StartPoint</span><span class="cls_004"> and </span><span class="cls_007">EndPoint</span><span class="cls_004"> properties and the</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_007"><span class="cls_007">StartPoint.Y</span><span class="cls_004"> property to </span><span class="cls_007">0</span><span class="cls_004"> and the </span><span class="cls_007">Endpoint</span><span class="cls_004"> </span><span class="cls_007">.Y</span><span class="cls_004"> property to </span><span class="cls_007">1</span><span class="cls_004">; plotting these points on a</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">graph will produce a vertical line and so, this produces a vertical gradient.</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">In the </span><span class="cls_007">GradientStops</span><span class="cls_004"> collection of the </span><span class="cls_007">LinearGradientBrush</span><span class="cls_004"> object, we have defined two</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_007"><span class="cls_007">GradientStop</span><span class="cls_004"> elements. The first has an offset of zero and is set to a white color, with a</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">hexadecimal alpha channel value of </span><span class="cls_007">BF</span><span class="cls_004">, which approximates an opacity value of </span><span class="cls_007">0.7</span><span class="cls_004">. The</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_004"><span class="cls_004">second has an offset of </span><span class="cls_007">0.8</span><span class="cls_004"> and is set to a white color that has a hexadecimal alpha</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_004"><span class="cls_004">channel value of </span><span class="cls_007">00</span><span class="cls_004">, which results in a completely transparent color and could be replaced</span></div>
<div style="position:absolute;left:5.00px;top:363.75px" class="cls_004"><span class="cls_004">with the </span><span class="cls_007">Transparent</span><span class="cls_004"> color.</span></div>
<div style="position:absolute;left:5.00px;top:381.75px" class="cls_004"><span class="cls_004">The resulting gradient therefore starts slightly transparent at the top and is fully transparent</span></div>
<div style="position:absolute;left:5.00px;top:399.75px" class="cls_004"><span class="cls_004">at the bottom which, with the bottom margin and offset values, is actually around the middle</span></div>
<div style="position:absolute;left:5.00px;top:417.75px" class="cls_004"><span class="cls_004">of the button. As with our other examples, the </span><span class="cls_007">ContentPresenter</span><span class="cls_004"> object is declared</span></div>
<div style="position:absolute;left:5.00px;top:435.75px" class="cls_004"><span class="cls_004">afterwards, so that it is rendered on top of the reflection effect.</span></div>
<div style="position:absolute;left:5.00px;top:453.01px" class="cls_011"><span class="cls_011">Creating glowing effects</span></div>
<div style="position:absolute;left:5.00px;top:483.00px" class="cls_004"><span class="cls_004">Another effect that we can create for our controls is that of a glowing appearance, as if a</span></div>
<div style="position:absolute;left:5.00px;top:501.00px" class="cls_004"><span class="cls_004">light were shining outwards from inside the control. We'll need another</span></div>
<div style="position:absolute;left:5.00px;top:519.00px" class="cls_007"><span class="cls_007">LinearGradientBrush</span><span class="cls_004"> instance and UI element to paint it on. A </span><span class="cls_007">Rectangle</span><span class="cls_004"> element suits this</span></div>
<div style="position:absolute;left:5.00px;top:537.00px" class="cls_004"><span class="cls_004">role well, as it's very light weight. We should define these resources in the application</span></div>
<div style="position:absolute;left:5.00px;top:555.00px" class="cls_004"><span class="cls_004">resources in the </span><span class="cls_007">App.xaml</span><span class="cls_004"> file to enable every View to use them.</span></div>
<div style="position:absolute;left:52.98px;top:578.25px" class="cls_007"><span class="cls_007"><TransformGroup x:Key="GlowTransformGroup"></span></div>
<div style="position:absolute;left:67.97px;top:591.75px" class="cls_007"><span class="cls_007"><ScaleTransform CenterX="0.5" CenterY="0.85" ScaleY="1.8" /></span></div>
<div style="position:absolute;left:67.97px;top:605.25px" class="cls_007"><span class="cls_007"><TranslateTransform Y="0.278" /></span></div>
<div style="position:absolute;left:52.98px;top:618.75px" class="cls_007"><span class="cls_007"></TransformGroup></span></div>
<div style="position:absolute;left:52.98px;top:632.25px" class="cls_007"><span class="cls_007"><RadialGradientBrush x:Key="GreenGlow" Center="0.5,0.848"</span></div>
<div style="position:absolute;left:67.97px;top:645.75px" class="cls_007"><span class="cls_007">GradientOrigin="0.5,0.818" RadiusX="-1.424" RadiusY="-0.622"</span></div>
<div style="position:absolute;left:67.97px;top:659.25px" class="cls_007"><span class="cls_007">RelativeTransform="{StaticResource GlowTransformGroup}"></span></div>
<div style="position:absolute;left:67.97px;top:672.75px" class="cls_007"><span class="cls_007"><GradientStop Color="#CF65FF00" Offset="0.168" /></span></div>
<div style="position:absolute;left:67.97px;top:686.25px" class="cls_007"><span class="cls_007"><GradientStop Color="#4B65FF00" Offset="0.478" /></span></div>
<div style="position:absolute;left:67.97px;top:699.75px" class="cls_007"><span class="cls_007"><GradientStop Color="#0065FF00" Offset="1" /></span></div>
<div style="position:absolute;left:52.98px;top:713.25px" class="cls_007"><span class="cls_007"></RadialGradientBrush></span></div>
<div style="position:absolute;left:52.98px;top:726.75px" class="cls_007"><span class="cls_007"><Style x:Key="GlowingButtonStyle" TargetType="{x:Type Button}"></span></div>
<div style="position:absolute;left:67.97px;top:740.25px" class="cls_007"><span class="cls_007"><Setter Property="SnapsToDevicePixels" Value="True" /></span></div>
<div style="position:absolute;left:67.97px;top:753.75px" class="cls_007"><span class="cls_007"><Setter Property="Template"></span></div>
<div style="position:absolute;left:82.97px;top:767.25px" class="cls_007"><span class="cls_007"><Setter.Value></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:223758px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background281.jpg" width=612 height=792></div>
<div style="position:absolute;left:97.96px;top:3.00px" class="cls_007"><span class="cls_007"><ControlTemplate TargetType="{x:Type Button}"></span></div>
<div style="position:absolute;left:112.96px;top:16.50px" class="cls_007"><span class="cls_007"><Border BorderBrush="White" BorderThickness="1"</span></div>
<div style="position:absolute;left:127.95px;top:30.00px" class="cls_007"><span class="cls_007">Background="DarkGray" CornerRadius="3"></span></div>
<div style="position:absolute;left:127.95px;top:43.50px" class="cls_007"><span class="cls_007"><Grid></span></div>
<div style="position:absolute;left:142.94px;top:57.00px" class="cls_007"><span class="cls_007"><Rectangle IsHitTestVisible="False" RadiusX="2"</span></div>
<div style="position:absolute;left:157.94px;top:70.50px" class="cls_007"><span class="cls_007">RadiusY="2" Fill="{StaticResource GreenGlow}" /></span></div>
<div style="position:absolute;left:142.94px;top:84.00px" class="cls_007"><span class="cls_007"><ContentPresenter Content="{TemplateBinding Content}"</span></div>
<div style="position:absolute;left:157.94px;top:97.50px" class="cls_007"><span class="cls_007">HorizontalAlignment="Center"</span></div>
<div style="position:absolute;left:52.98px;top:111.00px" class="cls_007"><span class="cls_007">VerticalAlignment="Center" /></span></div>
<div style="position:absolute;left:127.95px;top:124.50px" class="cls_007"><span class="cls_007"></Grid></span></div>
<div style="position:absolute;left:127.95px;top:138.00px" class="cls_007"><span class="cls_007"><Border.Effect></span></div>
<div style="position:absolute;left:142.94px;top:151.50px" class="cls_007"><span class="cls_007"><DropShadowEffect Color="#FF65FF00" ShadowDepth="4"</span></div>
<div style="position:absolute;left:157.94px;top:165.00px" class="cls_007"><span class="cls_007">Opacity="0.4" Direction="270" BlurRadius="10" /></span></div>
<div style="position:absolute;left:127.95px;top:178.50px" class="cls_007"><span class="cls_007"></Border.Effect></span></div>
<div style="position:absolute;left:112.96px;top:192.00px" class="cls_007"><span class="cls_007"></Border></span></div>
<div style="position:absolute;left:97.96px;top:205.50px" class="cls_007"><span class="cls_007"></ControlTemplate></span></div>
<div style="position:absolute;left:82.97px;top:219.00px" class="cls_007"><span class="cls_007"></Setter.Value></span></div>
<div style="position:absolute;left:67.97px;top:232.50px" class="cls_007"><span class="cls_007"></Setter></span></div>
<div style="position:absolute;left:52.98px;top:246.00px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:5.00px;top:266.25px" class="cls_004"><span class="cls_004">We start off by declaring a </span><span class="cls_007">TransformGroup</span><span class="cls_004"> element that enables us to group one or more</span></div>
<div style="position:absolute;left:5.00px;top:284.25px" class="cls_004"><span class="cls_004">transform objects together. Inside it, we define a </span><span class="cls_007">ScaleTransform</span><span class="cls_004"> element that scales</span></div>
<div style="position:absolute;left:5.00px;top:302.25px" class="cls_004"><span class="cls_004">applied elements vertically by the default factor of </span><span class="cls_007">1</span><span class="cls_004"> and horizontally by a factor of </span><span class="cls_007">1.8</span><span class="cls_004">. We</span></div>
<div style="position:absolute;left:5.00px;top:320.25px" class="cls_004"><span class="cls_004">specify the center of this transformation using its </span><span class="cls_007">CenterX</span><span class="cls_004"> and </span><span class="cls_007">Center</span><span class="cls_004"> </span><span class="cls_007">Y</span><span class="cls_004"> properties. Next,</span></div>
<div style="position:absolute;left:5.00px;top:338.25px" class="cls_004"><span class="cls_004">we declare a </span><span class="cls_007">TranslateTransform</span><span class="cls_004"> element that moves applied elements downwards by a</span></div>
<div style="position:absolute;left:5.00px;top:356.25px" class="cls_004"><span class="cls_004">small amount.</span></div>
<div style="position:absolute;left:5.00px;top:374.25px" class="cls_004"><span class="cls_004">After this, we define a </span><span class="cls_007">RadialGradientBrush</span><span class="cls_004"> object that will represent the glow in our</span></div>
<div style="position:absolute;left:5.00px;top:392.25px" class="cls_004"><span class="cls_004">design. We use the </span><span class="cls_007">RadiusX</span><span class="cls_004"> and </span><span class="cls_007">RadiusY</span><span class="cls_004"> properties to shape the brush element and</span></div>
<div style="position:absolute;left:5.00px;top:410.25px" class="cls_004"><span class="cls_004">specify the </span><span class="cls_007">Center</span><span class="cls_004"> and </span><span class="cls_007">GradientOrigin</span><span class="cls_004"> properties to dictate the center and focal point of</span></div>
<div style="position:absolute;left:5.00px;top:428.25px" class="cls_004"><span class="cls_004">the radial gradient.</span></div>
<div style="position:absolute;left:5.00px;top:446.25px" class="cls_004"><span class="cls_004">We then set the </span><span class="cls_007">TransformGroup</span><span class="cls_004"> element to the </span><span class="cls_007">RelativeTransform</span><span class="cls_004"> property of the brush</span></div>
<div style="position:absolute;left:5.00px;top:464.25px" class="cls_004"><span class="cls_004">to apply the transforms to it. Note that the three </span><span class="cls_007">GradientStop</span><span class="cls_004"> elements all use the same </span><span class="cls_007">R</span><span class="cls_004">,</span></div>
<div style="position:absolute;left:5.00px;top:482.25px" class="cls_007"><span class="cls_007">G</span><span class="cls_004"> and </span><span class="cls_007">B</span><span class="cls_004"> values, and just differ in alpha channel, or opacity values.</span></div>
<div style="position:absolute;left:5.00px;top:500.25px" class="cls_004"><span class="cls_004">Next, we declare the </span><span class="cls_007">GlowingButtonStyle</span><span class="cls_004"> style for the </span><span class="cls_007">Button</span><span class="cls_004"> type, setting the</span></div>
<div style="position:absolute;left:5.00px;top:518.25px" class="cls_007"><span class="cls_007">SnapsToDevicePixels</span><span class="cls_004"> property to </span><span class="cls_007">true</span><span class="cls_004">. In the </span><span class="cls_007">Template</span><span class="cls_004"> property, we define a</span></div>
<div style="position:absolute;left:5.00px;top:536.25px" class="cls_007"><span class="cls_007">ControlTemplate</span><span class="cls_004"> element, with a white </span><span class="cls_007">Border</span><span class="cls_004"> element with slightly rounded corners.</span></div>
<div style="position:absolute;left:5.00px;top:554.25px" class="cls_004"><span class="cls_004">Inside the border, we declare a </span><span class="cls_007">Grid</span><span class="cls_004"> panel containing a </span><span class="cls_007">Rectangle</span><span class="cls_004"> and a </span><span class="cls_007">ContentPresenter</span></div>
<div style="position:absolute;left:5.00px;top:572.25px" class="cls_004"><span class="cls_004">element. Again, the </span><span class="cls_007">RadiusX</span><span class="cls_004"> and </span><span class="cls_007">RadiusY</span><span class="cls_004"> properties of the rectangle are set to a smaller</span></div>
<div style="position:absolute;left:5.00px;top:590.25px" class="cls_004"><span class="cls_004">value than that of the </span><span class="cls_007">CornerRadius</span><span class="cls_004"> property of the parent border control to ensure that it</span></div>
<div style="position:absolute;left:5.00px;top:608.25px" class="cls_004"><span class="cls_004">fits evenly within it. Our </span><span class="cls_007">RadialGradientBrush</span><span class="cls_004"> resource is assigned as the rectangle's </span><span class="cls_007">Fill</span></div>
<div style="position:absolute;left:5.00px;top:626.25px" class="cls_004"><span class="cls_004">property.</span></div>
<div style="position:absolute;left:5.00px;top:644.25px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">ContentPresenter</span><span class="cls_004"> object is centered to ensure that the content of the button will be</span></div>
<div style="position:absolute;left:5.00px;top:662.25px" class="cls_004"><span class="cls_004">rendered in its center. Returning to the </span><span class="cls_007">Border</span><span class="cls_004"> element, we see a </span><span class="cls_007">DropShadowEffect</span><span class="cls_004"> that is</span></div>
<div style="position:absolute;left:5.00px;top:680.25px" class="cls_004"><span class="cls_004">declared within its </span><span class="cls_007">Effect</span><span class="cls_004"> property. However, this element is not here to create a shadow</span></div>
<div style="position:absolute;left:5.00px;top:698.25px" class="cls_004"><span class="cls_004">effect; this class is multi-functional and can also render glowing effects as well as shadow</span></div>
<div style="position:absolute;left:5.00px;top:716.25px" class="cls_004"><span class="cls_004">effects.</span></div>
<div style="position:absolute;left:5.00px;top:734.25px" class="cls_004"><span class="cls_004">The trick is to set its </span><span class="cls_007">Color</span><span class="cls_004"> property to a color other than black and to set its </span><span class="cls_007">BlurRadius</span></div>
<div style="position:absolute;left:5.00px;top:752.25px" class="cls_004"><span class="cls_004">property to a larger value than we would typically use when creating a shadow effect. In</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:224560px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background282.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">our particular case, we set the </span><span class="cls_007">Direction</span><span class="cls_004"> property to </span><span class="cls_007">270</span><span class="cls_004"> and </span><span class="cls_007">ShadowDepth</span><span class="cls_004"> property to </span><span class="cls_007">4</span><span class="cls_004"> in</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">order to position the glow effect towards the bottom of the border. where the light is</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">supposed to be coming from.</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">Unfortunately, this effect does not translate to gray scale and paper well, so the glowing</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">effect is somewhat lost when not viewed in color and on screen. For the readers of the e-</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">book version of this book, here is what the glowing effect from our example looks like.</span></div>
<div style="position:absolute;left:5.00px;top:178.51px" class="cls_011"><span class="cls_011">Putting it all together</span></div>
<div style="position:absolute;left:5.00px;top:208.50px" class="cls_004"><span class="cls_004">While these various effects can improve the look of our controls on their own, the biggest</span></div>
<div style="position:absolute;left:5.00px;top:226.50px" class="cls_004"><span class="cls_004">improvement can be found when amalgamating a number of them into a single design. In</span></div>
<div style="position:absolute;left:5.00px;top:244.50px" class="cls_004"><span class="cls_004">this next example, we'll do just that. We first need to add a few more resources to use.</span></div>
<div style="position:absolute;left:52.98px;top:267.75px" class="cls_007"><span class="cls_007"><SolidColorBrush x:Key="TransparentWhite" Color="#7FFFFFFF" /></span></div>
<div style="position:absolute;left:52.98px;top:281.25px" class="cls_007"><span class="cls_007"><SolidColorBrush x:Key="VeryTransparentWhite" Color="#3FFFFFFF" /></span></div>
<div style="position:absolute;left:52.98px;top:294.75px" class="cls_007"><span class="cls_007"><SolidColorBrush x:Key="TransparentBlack" Color="#7F000000" /></span></div>
<div style="position:absolute;left:52.98px;top:308.25px" class="cls_007"><span class="cls_007"><SolidColorBrush x:Key="VeryTransparentBlack" Color="#3F000000" /></span></div>
<div style="position:absolute;left:52.98px;top:321.75px" class="cls_007"><span class="cls_007"><VisualBrush x:Key="SemiTransparentLayeredButtonBackground"</span></div>
<div style="position:absolute;left:67.97px;top:335.25px" class="cls_007"><span class="cls_007">Visual="{StaticResource LayeredButtonBackgroundElements}"</span></div>
<div style="position:absolute;left:67.97px;top:348.75px" class="cls_007"><span class="cls_007">Opacity="0.65" /></span></div>
<div style="position:absolute;left:5.00px;top:369.00px" class="cls_004"><span class="cls_004">There isn't anything too complicated here. We simply have a number of colors defined with</span></div>
<div style="position:absolute;left:5.00px;top:387.00px" class="cls_004"><span class="cls_004">varying levels of transparency and a slightly transparent version of our visual brush that</span></div>
<div style="position:absolute;left:5.00px;top:405.00px" class="cls_004"><span class="cls_004">references our layered background elements. Let's move on to the encompassing style</span></div>
<div style="position:absolute;left:5.00px;top:423.00px" class="cls_004"><span class="cls_004">now.</span></div>
<div style="position:absolute;left:52.98px;top:446.25px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type Button}"></span></div>
<div style="position:absolute;left:67.97px;top:459.75px" class="cls_007"><span class="cls_007"><Setter Property="SnapsToDevicePixels" Value="True" /></span></div>
<div style="position:absolute;left:67.97px;top:473.25px" class="cls_007"><span class="cls_007"><Setter Property="Cursor" Value="Hand" /></span></div>
<div style="position:absolute;left:67.97px;top:486.75px" class="cls_007"><span class="cls_007"><Setter Property="Template"></span></div>
<div style="position:absolute;left:82.97px;top:500.25px" class="cls_007"><span class="cls_007"><Setter.Value></span></div>
<div style="position:absolute;left:97.96px;top:513.75px" class="cls_007"><span class="cls_007"><ControlTemplate TargetType="{x:Type Button}"></span></div>
<div style="position:absolute;left:112.96px;top:527.25px" class="cls_007"><span class="cls_007"><Border CornerRadius="3"</span></div>
<div style="position:absolute;left:127.95px;top:540.75px" class="cls_007"><span class="cls_007">BorderBrush="{StaticResource TransparentBlack}"</span></div>
<div style="position:absolute;left:127.95px;top:554.25px" class="cls_007"><span class="cls_007">BorderThickness="1"</span></div>
<div style="position:absolute;left:127.95px;top:567.75px" class="cls_007"><span class="cls_007">Background="{StaticResource TransparentWhite}"></span></div>
<div style="position:absolute;left:127.95px;top:581.25px" class="cls_007"><span class="cls_007"><Border Name="InnerBorder" CornerRadius="2"</span></div>
<div style="position:absolute;left:142.94px;top:594.75px" class="cls_007"><span class="cls_007">Background="{StaticResource LayeredButtonBackground}"</span></div>
<div style="position:absolute;left:142.94px;top:608.25px" class="cls_007"><span class="cls_007">Margin="1"></span></div>
<div style="position:absolute;left:142.94px;top:621.75px" class="cls_007"><span class="cls_007"><Grid></span></div>
<div style="position:absolute;left:157.94px;top:635.25px" class="cls_007"><span class="cls_007"><Rectangle IsHitTestVisible="False" RadiusX="2"</span></div>
<div style="position:absolute;left:172.93px;top:648.75px" class="cls_007"><span class="cls_007">RadiusY="2" Fill="{StaticResource GreenGlow}" /></span></div>
<div style="position:absolute;left:157.94px;top:662.25px" class="cls_007"><span class="cls_007"><ContentPresenter Content="{TemplateBinding Content}"</span></div>
<div style="position:absolute;left:172.93px;top:675.75px" class="cls_007"><span class="cls_007">Margin="{TemplateBinding Padding}"</span></div>
<div style="position:absolute;left:172.93px;top:689.25px" class="cls_007"><span class="cls_007">HorizontalAlignment="{TemplateBinding</span></div>
<div style="position:absolute;left:172.93px;top:702.75px" class="cls_007"><span class="cls_007">HorizontalContentAlignment}"</span></div>
<div style="position:absolute;left:172.93px;top:716.25px" class="cls_007"><span class="cls_007">VerticalAlignment="{TemplateBinding</span></div>
<div style="position:absolute;left:172.93px;top:729.75px" class="cls_007"><span class="cls_007">VerticalContentAlignment}" /></span></div>
<div style="position:absolute;left:142.94px;top:743.25px" class="cls_007"><span class="cls_007"></Grid></span></div>
<div style="position:absolute;left:127.95px;top:756.75px" class="cls_007"><span class="cls_007"></Border></span></div>
<div style="position:absolute;left:127.95px;top:770.25px" class="cls_007"><span class="cls_007"><Border.Effect></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:225362px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background283.jpg" width=612 height=792></div>
<div style="position:absolute;left:142.94px;top:3.00px" class="cls_007"><span class="cls_007"><DropShadowEffect Color="Black" ShadowDepth="6"</span></div>
<div style="position:absolute;left:157.94px;top:16.50px" class="cls_007"><span class="cls_007">BlurRadius="6" Direction="270" Opacity="0.5" /></span></div>
<div style="position:absolute;left:127.95px;top:30.00px" class="cls_007"><span class="cls_007"></Border.Effect></span></div>
<div style="position:absolute;left:112.96px;top:43.50px" class="cls_007"><span class="cls_007"></Border></span></div>
<div style="position:absolute;left:112.96px;top:57.00px" class="cls_007"><span class="cls_007"><ControlTemplate.Triggers></span></div>
<div style="position:absolute;left:127.95px;top:70.50px" class="cls_007"><span class="cls_007"><Trigger Property="IsMouseOver" Value="True"></span></div>
<div style="position:absolute;left:142.94px;top:84.00px" class="cls_007"><span class="cls_007"><Setter TargetName="InnerBorder"</span></div>
<div style="position:absolute;left:157.94px;top:97.50px" class="cls_007"><span class="cls_007">Property="Background" Value="{StaticResource</span></div>
<div style="position:absolute;left:157.94px;top:111.00px" class="cls_007"><span class="cls_007">SemiTransparentLayeredButtonBackground}" /></span></div>
<div style="position:absolute;left:127.95px;top:124.50px" class="cls_007"><span class="cls_007"></Trigger></span></div>
<div style="position:absolute;left:127.95px;top:138.00px" class="cls_007"><span class="cls_007"><Trigger Property="IsPressed" Value="True"></span></div>
<div style="position:absolute;left:142.94px;top:151.50px" class="cls_007"><span class="cls_007"><Setter TargetName="InnerBorder" Property="Background"</span></div>
<div style="position:absolute;left:157.94px;top:165.00px" class="cls_007"><span class="cls_007">Value="{StaticResource LayeredButtonBackground}" /></span></div>
<div style="position:absolute;left:127.95px;top:178.50px" class="cls_007"><span class="cls_007"></Trigger></span></div>
<div style="position:absolute;left:112.96px;top:192.00px" class="cls_007"><span class="cls_007"></ControlTemplate.Triggers></span></div>
<div style="position:absolute;left:97.96px;top:205.50px" class="cls_007"><span class="cls_007"></ControlTemplate></span></div>
<div style="position:absolute;left:82.97px;top:219.00px" class="cls_007"><span class="cls_007"></Setter.Value></span></div>
<div style="position:absolute;left:67.97px;top:232.50px" class="cls_007"><span class="cls_007"></Setter></span></div>
<div style="position:absolute;left:52.98px;top:246.00px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:5.00px;top:266.25px" class="cls_004"><span class="cls_004">First note that we have omitted the </span><span class="cls_007">x:Key</span><span class="cls_004"> directive on this style, so that it will be implicitly</span></div>
<div style="position:absolute;left:5.00px;top:284.25px" class="cls_004"><span class="cls_004">applied to all </span><span class="cls_007">Button</span><span class="cls_004"> elements that do not explicitly apply a different style. We are therefore</span></div>
<div style="position:absolute;left:5.00px;top:302.25px" class="cls_004"><span class="cls_004">able to declare our </span><span class="cls_007">Button</span><span class="cls_004"> elements without specifying the style, like the following code</span></div>
<div style="position:absolute;left:5.00px;top:320.25px" class="cls_004"><span class="cls_004">snippet:</span></div>
<div style="position:absolute;left:52.98px;top:343.50px" class="cls_007"><span class="cls_007"><Button Content="Click Me" Width="200" Height="40" FontSize="20"</span></div>
<div style="position:absolute;left:67.97px;top:357.00px" class="cls_007"><span class="cls_007">Foreground="White" /></span></div>
<div style="position:absolute;left:5.00px;top:377.25px" class="cls_004"><span class="cls_004">This results in the following visual output:</span></div>
<div style="position:absolute;left:5.00px;top:471.75px" class="cls_004"><span class="cls_004">Looking at the example XAML, we see that the </span><span class="cls_007">SnapsToDevicePixels</span><span class="cls_004"> property is set to</span></div>
<div style="position:absolute;left:5.00px;top:489.75px" class="cls_007"><span class="cls_007">true</span><span class="cls_004">, to avoid anti-aliasing artefacts blurring the edges of the button, and the </span><span class="cls_007">Cursor</span></div>
<div style="position:absolute;left:5.00px;top:507.75px" class="cls_004"><span class="cls_004">property is set to display the pointing finger cursor when the user's mouse is over the</span></div>
<div style="position:absolute;left:5.00px;top:525.75px" class="cls_004"><span class="cls_004">button.</span></div>
<div style="position:absolute;left:5.00px;top:543.75px" class="cls_004"><span class="cls_004">Within the control template, we see the two nested </span><span class="cls_007">Border</span><span class="cls_004"> elements. Note that the outer</span></div>
<div style="position:absolute;left:5.00px;top:561.75px" class="cls_004"><span class="cls_004">border uses the </span><span class="cls_007">TransparentBlack</span><span class="cls_004"> and </span><span class="cls_007">TransparentWhite</span><span class="cls_004"> brush resources, so that it is</span></div>
<div style="position:absolute;left:5.00px;top:579.75px" class="cls_004"><span class="cls_004">semi-transparent. Also note that the white inner border actually comes from the background</span></div>
<div style="position:absolute;left:5.00px;top:597.75px" class="cls_004"><span class="cls_004">of the outer border, rather than the inner border, which sets the </span><span class="cls_007">Margin</span><span class="cls_004"> property to </span><span class="cls_007">1</span><span class="cls_004"> to give</span></div>
<div style="position:absolute;left:5.00px;top:615.75px" class="cls_004"><span class="cls_004">the impression of an inner border.</span></div>
<div style="position:absolute;left:5.00px;top:633.75px" class="cls_004"><span class="cls_004">In this example, the inner border element is only responsible for displaying the layered</span></div>
<div style="position:absolute;left:5.00px;top:651.75px" class="cls_004"><span class="cls_004">button elements from the visual brush and has no displayed border of its own. Again, we</span></div>
<div style="position:absolute;left:5.00px;top:669.75px" class="cls_004"><span class="cls_004">have adjusted its </span><span class="cls_007">CornerRadius</span><span class="cls_004"> property so that it fits neatly within the outer border. We</span></div>
<div style="position:absolute;left:5.00px;top:687.75px" class="cls_004"><span class="cls_004">can zoom in the magnification level in the WPF designer to help us to decide what values</span></div>
<div style="position:absolute;left:5.00px;top:705.75px" class="cls_004"><span class="cls_004">we should use here.</span></div>
<div style="position:absolute;left:5.00px;top:723.75px" class="cls_004"><span class="cls_004">Inside the inner border, we declare a </span><span class="cls_007">Grid</span><span class="cls_004"> panel, so that we can add both the required</span></div>
<div style="position:absolute;left:5.00px;top:741.75px" class="cls_007"><span class="cls_007">ContentPresenter</span><span class="cls_004"> and the </span><span class="cls_007">Rectangle</span><span class="cls_004"> element that is painted with the </span><span class="cls_007">GreenGlow</span><span class="cls_004"> brush from</span></div>
<div style="position:absolute;left:5.00px;top:759.75px" class="cls_004"><span class="cls_004">resources. Again, we set its </span><span class="cls_007">IsHitTestVisible</span><span class="cls_004"> property to </span><span class="cls_007">false</span><span class="cls_004">, so that users cannot</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:226164px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background284.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">interact with it and set the </span><span class="cls_007">RadiusX</span><span class="cls_004"> and </span><span class="cls_007">RadiusY</span><span class="cls_004"> properties to match the </span><span class="cls_007">CornerRadius</span><span class="cls_004"> value</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">of the inner border.</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">We use </span><span class="cls_007">TemplateBinding</span><span class="cls_004"> elements to map properties of the </span><span class="cls_007">ContentPresenter</span><span class="cls_004"> object to</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">suitable properties from the templated object, so that setting properties on our button can</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">affect its positioning and content. Next, we set the previously displayed </span><span class="cls_007">DropShadowEffect</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">element to the </span><span class="cls_007">Effect</span><span class="cls_004"> property of the outer border and that sums up the contained UI</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">elements in the template.</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">To make the template more useful, we have set some </span><span class="cls_007">Trigger</span><span class="cls_004"> objects in the</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_007"><span class="cls_007">ControlTemplate.Triggers</span><span class="cls_004"> collection, that will add mouse over effects for our button. The</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">first trigger targets the </span><span class="cls_007">IsMouseOver</span><span class="cls_004"> property and sets the background of the inner border</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">to the slightly more transparent version of the layered button elements visual brush when</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">true.</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">The second trigger targets the </span><span class="cls_007">IsPressed</span><span class="cls_004"> property and re-applies the original visual brush</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">when the property is true. Note that these two triggers must be defined in this order, so that</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">the one that targets the </span><span class="cls_007">IsPressed</span><span class="cls_004"> property will override the other when both conditions are</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">true. It is of course, a matter of taste, whether the button lights up or goes out when</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">clicked, or perhaps even changes color.</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">We could take this glowing idea further too, by defining a number of different color</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_004"><span class="cls_004">resources and using data triggers inside a data template to change the color of the glow to</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_004"><span class="cls_004">indicate different states of a data object. This enables us to provide further visual</span></div>
<div style="position:absolute;left:5.00px;top:363.75px" class="cls_004"><span class="cls_004">information to the users, in addition to the usual textual feedback methods.</span></div>
<div style="position:absolute;left:5.00px;top:381.75px" class="cls_004"><span class="cls_004">For example, a blue glow on a data model object could specify an unchanged object, while</span></div>
<div style="position:absolute;left:5.00px;top:399.75px" class="cls_004"><span class="cls_004">green could signify an object with valid changes and red could highlight an object in error.</span></div>
<div style="position:absolute;left:5.00px;top:417.75px" class="cls_004"><span class="cls_004">We'll see how we can implement this idea in the next chapter, but for now, let's continue</span></div>
<div style="position:absolute;left:5.00px;top:435.75px" class="cls_004"><span class="cls_004">looking at different ways to make our applications stand out from the crowd.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:226966px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background285.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_008"><span class="cls_008">Moving away from the ordinary</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">The vast majority of business applications in general, look fairly ordinary, with various form</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">pages containing banks of standard rectangular form fields. Visually appealing applications</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">on the other hand, stand out from the crowd. Therefore, in order to create visually</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">appealing applications, we need to move away from the ordinary.</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">Whether this means simply adding control templates with rounded corners for our controls,</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">or something more is up to you. There are many different ways that we can enhance the</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">look of our controls and we'll take a look at a number of these ideas in this section. Let's</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">start with a refection effect that is best suited for use with logos, or startup or background</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">images.</span></div>
<div style="position:absolute;left:5.00px;top:201.01px" class="cls_011"><span class="cls_011">Casting reflections</span></div>
<div style="position:absolute;left:5.00px;top:231.00px" class="cls_004"><span class="cls_004">All </span><span class="cls_007">FrameworkElement</span><span class="cls_004">-derived classes have a </span><span class="cls_007">RenderTransform</span><span class="cls_004"> property that we can utilize</span></div>
<div style="position:absolute;left:5.00px;top:249.00px" class="cls_004"><span class="cls_004">to transform their rendered output in a variety of ways. A </span><span class="cls_007">ScaleTransform</span><span class="cls_004"> element enables</span></div>
<div style="position:absolute;left:5.00px;top:267.00px" class="cls_004"><span class="cls_004">us to scale each object in both horizontal and vertical directions. One useful facet about the</span></div>
<div style="position:absolute;left:5.00px;top:285.00px" class="cls_007"><span class="cls_007">ScaleTransform</span><span class="cls_004"> object is that we can also scale negatively, and therefore reverse the visual</span></div>
<div style="position:absolute;left:5.00px;top:303.00px" class="cls_004"><span class="cls_004">output.</span></div>
<div style="position:absolute;left:5.00px;top:321.00px" class="cls_004"><span class="cls_004">One visually pleasing effect that we can create with this particular facet is a mirror image,</span></div>
<div style="position:absolute;left:5.00px;top:339.00px" class="cls_004"><span class="cls_004">or reflection of the object. In order to enhance this effect, we can use an opacity mask to</span></div>
<div style="position:absolute;left:5.00px;top:357.00px" class="cls_004"><span class="cls_004">fade out the reflection as it recedes from the object. This can give the visual impression of</span></div>
<div style="position:absolute;left:5.00px;top:375.00px" class="cls_004"><span class="cls_004">an object sitting on a table, being reflected in the shiny surface, as shown in the following</span></div>
<div style="position:absolute;left:5.00px;top:393.00px" class="cls_004"><span class="cls_004">image:</span></div>
<div style="position:absolute;left:5.00px;top:496.50px" class="cls_004"><span class="cls_004">Let's see how we can achieve this result.</span></div>
<div style="position:absolute;left:52.98px;top:519.75px" class="cls_007"><span class="cls_007"><StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"</span></div>
<div style="position:absolute;left:67.97px;top:533.25px" class="cls_007"><span class="cls_007">Width="348"></span></div>
<div style="position:absolute;left:67.97px;top:546.75px" class="cls_007"><span class="cls_007"><TextBlock Name="TextBlock" FontFamily="Candara"</span></div>
<div style="position:absolute;left:82.97px;top:560.25px" class="cls_007"><span class="cls_007">Text="APPLICATION NAME" FontSize="40" FontWeight="Bold"></span></div>
<div style="position:absolute;left:82.97px;top:573.75px" class="cls_007"><span class="cls_007"><TextBlock.Foreground></span></div>
<div style="position:absolute;left:97.96px;top:587.25px" class="cls_007"><span class="cls_007"><LinearGradientBrush StartPoint="0,0" EndPoint="1,0"></span></div>
<div style="position:absolute;left:112.96px;top:600.75px" class="cls_007"><span class="cls_007"><GradientStop Color="Orange" /></span></div>
<div style="position:absolute;left:112.96px;top:614.25px" class="cls_007"><span class="cls_007"><GradientStop Color="Red" Offset="0.5" /></span></div>
<div style="position:absolute;left:112.96px;top:627.75px" class="cls_007"><span class="cls_007"><GradientStop Color="Orange" Offset="1" /></span></div>
<div style="position:absolute;left:97.96px;top:641.25px" class="cls_007"><span class="cls_007"></LinearGradientBrush></span></div>
<div style="position:absolute;left:82.97px;top:654.75px" class="cls_007"><span class="cls_007"></TextBlock.Foreground></span></div>
<div style="position:absolute;left:67.97px;top:668.25px" class="cls_007"><span class="cls_007"></TextBlock></span></div>
<div style="position:absolute;left:67.97px;top:681.75px" class="cls_007"><span class="cls_007"><Rectangle Height="31" Margin="0,-11.6,0,0"></span></div>
<div style="position:absolute;left:82.97px;top:695.25px" class="cls_007"><span class="cls_007"><Rectangle.Fill></span></div>
<div style="position:absolute;left:97.96px;top:708.75px" class="cls_007"><span class="cls_007"><VisualBrush Visual="{Binding ElementName=TextBlock}"></span></div>
<div style="position:absolute;left:112.96px;top:722.25px" class="cls_007"><span class="cls_007"><VisualBrush.RelativeTransform></span></div>
<div style="position:absolute;left:127.95px;top:735.75px" class="cls_007"><span class="cls_007"><ScaleTransform ScaleY="-1.0" CenterX="0.5" CenterY="0.5"</span></div>
<div style="position:absolute;left:52.98px;top:749.25px" class="cls_007"><span class="cls_007">/></span></div>
<div style="position:absolute;left:112.96px;top:762.75px" class="cls_007"><span class="cls_007"></VisualBrush.RelativeTransform></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:227768px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background286.jpg" width=612 height=792></div>
<div style="position:absolute;left:97.96px;top:3.00px" class="cls_007"><span class="cls_007"></VisualBrush></span></div>
<div style="position:absolute;left:82.97px;top:16.50px" class="cls_007"><span class="cls_007"></Rectangle.Fill></span></div>
<div style="position:absolute;left:82.97px;top:30.00px" class="cls_007"><span class="cls_007"><Rectangle.OpacityMask></span></div>
<div style="position:absolute;left:97.96px;top:43.50px" class="cls_007"><span class="cls_007"><LinearGradientBrush StartPoint="0,0" EndPoint="0,1"></span></div>
<div style="position:absolute;left:112.96px;top:57.00px" class="cls_007"><span class="cls_007"><GradientStop Color="#DF000000" /></span></div>
<div style="position:absolute;left:112.96px;top:70.50px" class="cls_007"><span class="cls_007"><GradientStop Color="Transparent" Offset="0.8" /></span></div>
<div style="position:absolute;left:97.96px;top:84.00px" class="cls_007"><span class="cls_007"></LinearGradientBrush></span></div>
<div style="position:absolute;left:82.97px;top:97.50px" class="cls_007"><span class="cls_007"></Rectangle.OpacityMask></span></div>
<div style="position:absolute;left:67.97px;top:111.00px" class="cls_007"><span class="cls_007"></Rectangle></span></div>
<div style="position:absolute;left:52.98px;top:124.50px" class="cls_007"><span class="cls_007"></StackPanel></span></div>
<div style="position:absolute;left:5.00px;top:157.50px" class="cls_004"><span class="cls_004">In this example, we use a </span><span class="cls_007">StackPanel</span><span class="cls_004"> object to position a </span><span class="cls_007">TextBlock</span><span class="cls_004"> element above a</span></div>
<div style="position:absolute;left:5.00px;top:175.50px" class="cls_007"><span class="cls_007">Rectangle</span><span class="cls_004"> element. The text will be the object to reflect and the reflection will be generated</span></div>
<div style="position:absolute;left:5.00px;top:193.50px" class="cls_004"><span class="cls_004">in the rectangle. The panel's width is constrained to ensure that the reflection fits the text</span></div>
<div style="position:absolute;left:5.00px;top:211.50px" class="cls_004"><span class="cls_004">element exactly. We start by naming the </span><span class="cls_007">TextBlock</span><span class="cls_004"> element and setting some typeface</span></div>
<div style="position:absolute;left:5.00px;top:229.50px" class="cls_004"><span class="cls_004">properties, along with the text to output.</span></div>
<div style="position:absolute;left:5.00px;top:247.50px" class="cls_004"><span class="cls_004">We've set a </span><span class="cls_007">LinearGradientBrush</span><span class="cls_004"> object as the color for the text to make it more</span></div>
<div style="position:absolute;left:5.00px;top:265.50px" class="cls_004"><span class="cls_004">interesting, although this plays no part in creating the reflection effect. Next, note that the</span></div>
<div style="position:absolute;left:5.00px;top:283.50px" class="cls_007"><span class="cls_007">Rectangle</span><span class="cls_004"> element is sized and positioned exactly to fit the size of the text from the</span></div>
<div style="position:absolute;left:5.00px;top:301.50px" class="cls_007"><span class="cls_007">TextBlock</span><span class="cls_004"> element. We can of course use this technique to reflect anything and are not</span></div>
<div style="position:absolute;left:5.00px;top:319.50px" class="cls_004"><span class="cls_004">restricted to just reflecting text elements.</span></div>
<div style="position:absolute;left:5.00px;top:337.50px" class="cls_004"><span class="cls_004">The background of the rectangle is painted with a </span><span class="cls_007">VisualBrush</span><span class="cls_004"> object, where the </span><span class="cls_007">Visual</span></div>
<div style="position:absolute;left:5.00px;top:355.50px" class="cls_004"><span class="cls_004">property is data bound to the visual output of the </span><span class="cls_007">TextBlock</span><span class="cls_004"> element, using the </span><span class="cls_007">ElementName</span></div>
<div style="position:absolute;left:5.00px;top:373.50px" class="cls_004"><span class="cls_004">property. Note the </span><span class="cls_007">RelativeTransform</span><span class="cls_004"> property of the </span><span class="cls_007">VisualBrush</span><span class="cls_004"> object, enables us to</span></div>
<div style="position:absolute;left:5.00px;top:391.50px" class="cls_004"><span class="cls_004">transform the visual in some way and is set to an instance of the </span><span class="cls_007">ScaleTransform</span><span class="cls_004"> class.</span></div>
<div style="position:absolute;left:5.00px;top:409.50px" class="cls_004"><span class="cls_004">This is one of the most important constituents for creating this effect, as this element is</span></div>
<div style="position:absolute;left:5.00px;top:427.50px" class="cls_004"><span class="cls_004">what inverts the related visual in the vertical plain. Setting the </span><span class="cls_007">ScaleY</span><span class="cls_004"> property to </span><span class="cls_007">-1</span><span class="cls_004"> will</span></div>
<div style="position:absolute;left:5.00px;top:445.50px" class="cls_004"><span class="cls_004">invert the visual vertically for us, while setting the </span><span class="cls_007">ScaleX</span><span class="cls_004"> property to </span><span class="cls_007">-1</span><span class="cls_004"> would invert the</span></div>
<div style="position:absolute;left:5.00px;top:463.50px" class="cls_004"><span class="cls_004">visual horizontally. Note that we omit the </span><span class="cls_007">ScaleX</span><span class="cls_004"> property here because we want it set at its</span></div>
<div style="position:absolute;left:5.00px;top:481.50px" class="cls_004"><span class="cls_004">default value of </span><span class="cls_007">1</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:499.50px" class="cls_004"><span class="cls_004">Next, we see the </span><span class="cls_007">OpacityMask</span><span class="cls_004"> property, which lets us set a gradient brush to be mapped to</span></div>
<div style="position:absolute;left:5.00px;top:517.50px" class="cls_004"><span class="cls_004">the opacity of the rectangle. When the alpha channel of the brush is </span><span class="cls_007">1</span><span class="cls_004">, the rectangle will be</span></div>
<div style="position:absolute;left:5.00px;top:535.50px" class="cls_004"><span class="cls_004">opaque, when it is </span><span class="cls_007">0</span><span class="cls_004">, the rectangle will be transparent and when it is in between, the</span></div>
<div style="position:absolute;left:5.00px;top:553.50px" class="cls_004"><span class="cls_004">rectangle will be semi-transparent. This is the other essential part of this effect and creates</span></div>
<div style="position:absolute;left:5.00px;top:571.50px" class="cls_004"><span class="cls_004">the fade of the reflected image.</span></div>
<div style="position:absolute;left:5.00px;top:589.50px" class="cls_004"><span class="cls_004">In our example, we have a vertical gradient that is almost solid black at the top and gets</span></div>
<div style="position:absolute;left:5.00px;top:607.50px" class="cls_004"><span class="cls_004">increasingly transparent until it reaches four fifths of the way down, when it becomes fully</span></div>
<div style="position:absolute;left:5.00px;top:625.50px" class="cls_004"><span class="cls_004">transparent. When set as the rectangle's </span><span class="cls_007">OpacityMask</span><span class="cls_004">, only the alpha channel values are</span></div>
<div style="position:absolute;left:5.00px;top:643.50px" class="cls_004"><span class="cls_004">used and this results in it being totally visible at the top and fading to invisibility four fifths of</span></div>
<div style="position:absolute;left:5.00px;top:661.50px" class="cls_004"><span class="cls_004">the way down, as shown in the preceding image.</span></div>
<div style="position:absolute;left:5.00px;top:678.76px" class="cls_011"><span class="cls_011">Exploring borderless windows</span></div>
<div style="position:absolute;left:5.00px;top:708.75px" class="cls_004"><span class="cls_004">Using WPF, it is possible to create windows without borders, a title bar and the standard</span></div>
<div style="position:absolute;left:5.00px;top:726.75px" class="cls_004"><span class="cls_004">minimize, restore and close buttons. It is also possible to create irregular shaped windows</span></div>
<div style="position:absolute;left:5.00px;top:744.75px" class="cls_004"><span class="cls_004">and windows with transparent areas that display whatever lies beneath. Although it would</span></div>
<div style="position:absolute;left:5.00px;top:762.75px" class="cls_004"><span class="cls_004">be somewhat unconventional to make our main application window borderless, we can still</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:228570px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background287.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">take advantage of this ability.</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">For example, we could create a borderless window for custom message boxes, or perhaps</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">for extended tooltips, or any other popup control that provides information to the end user.</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">Creating borderless windows can be achieved within a few simple steps. Let's start with the</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">basics and assume that we're adding this to our existing application framework.</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">In this case, we've already got our </span><span class="cls_007">MainWindow</span><span class="cls_004"> class and need to add an additional window.</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">Probably, one of the easiest way to do this in Visual Studio, is to add a WPF User Control</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">class into our </span><span class="cls_007">Controls</span><span class="cls_004"> folder and then simply replace the word </span><span class="cls_007">UserControl</span><span class="cls_004"> with the word</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_007"><span class="cls_007">Window</span><span class="cls_004"> in both the XAML file and its associated code behind file.</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">All we need to do now is to set the window's </span><span class="cls_007">WindowStyle</span><span class="cls_004"> property to </span><span class="cls_007">None</span><span class="cls_004"> and its</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_007"><span class="cls_007">AllowsTransparency</span><span class="cls_004"> property to true. This will result in the white background of our</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">window's declared size appearing.</span></div>
<div style="position:absolute;left:52.98px;top:225.00px" class="cls_007"><span class="cls_007"><Window</span></div>
<div style="position:absolute;left:52.98px;top:252.00px" class="cls_007"><span class="cls_007">x:Class="CompanyName.ApplicationName.Views.Controls.BorderlessWindo</span></div>
<div style="position:absolute;left:52.98px;top:265.50px" class="cls_007"><span class="cls_007">w"</span></div>
<div style="position:absolute;left:67.97px;top:279.00px" class="cls_007"><span class="cls_007">xmlns="</span><A HREF="http://schemas.microsoft.com/winfx/2006/xaml/presentation"/">http://schemas.microsoft.com/winfx/2006/xaml/presentation"</A> </div>
<div style="position:absolute;left:67.97px;top:292.50px" class="cls_007"><span class="cls_007">xmlns:x="</span><A HREF="http://schemas.microsoft.com/winfx/2006/xaml"/">http://schemas.microsoft.com/winfx/2006/xaml"</A> </div>
<div style="position:absolute;left:67.97px;top:306.00px" class="cls_007"><span class="cls_007">xmlns:mc="</span><A HREF="http://schemas.openxmlformats.org/markup-/">http://schemas.openxmlformats.org/markup-</A> </div>
<div style="position:absolute;left:52.98px;top:319.50px" class="cls_007"><span class="cls_007">compatibility/2006"</span></div>
<div style="position:absolute;left:67.97px;top:333.00px" class="cls_007"><span class="cls_007">xmlns:d="</span><A HREF="http://schemas.microsoft.com/expression/blend/2008"/">http://schemas.microsoft.com/expression/blend/2008"</A> </div>
<div style="position:absolute;left:67.97px;top:346.50px" class="cls_007"><span class="cls_007">mc:Ignorable="d"</span></div>
<div style="position:absolute;left:67.97px;top:360.00px" class="cls_007"><span class="cls_007">Height="150" Width="300"</span></div>
<div style="position:absolute;left:52.98px;top:373.50px" class="cls_007"><span class="cls_007">WindowStyle="None"AllowsTransparency="True"></span></div>
<div style="position:absolute;left:52.98px;top:387.00px" class="cls_007"><span class="cls_007"></Window></span></div>
<div style="position:absolute;left:52.98px;top:441.00px" class="cls_007"><span class="cls_007">using System.Windows;</span></div>
<div style="position:absolute;left:52.98px;top:468.00px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.Views.Controls</span></div>
<div style="position:absolute;left:52.98px;top:481.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:495.00px" class="cls_007"><span class="cls_007">public partial class BorderlessWindow : Window</span></div>
<div style="position:absolute;left:67.97px;top:508.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:522.00px" class="cls_007"><span class="cls_007">public BorderlessWindow()</span></div>
<div style="position:absolute;left:82.97px;top:535.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:549.00px" class="cls_007"><span class="cls_007">InitializeComponent();</span></div>
<div style="position:absolute;left:82.97px;top:562.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:576.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:589.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:622.50px" class="cls_004"><span class="cls_004">However, while this removes the default window chrome that we are all used to and</span></div>
<div style="position:absolute;left:5.00px;top:640.50px" class="cls_004"><span class="cls_004">provides us with a borderless window, it also removes the standard buttons, so we are</span></div>
<div style="position:absolute;left:5.00px;top:658.50px" class="cls_004"><span class="cls_004">unable to close, resize or even move the window directly. Luckily, making our window</span></div>
<div style="position:absolute;left:5.00px;top:676.50px" class="cls_004"><span class="cls_004">moveable is a very simple matter. We just need to add the following line of code into our</span></div>
<div style="position:absolute;left:5.00px;top:694.50px" class="cls_004"><span class="cls_004">window's constructor after the </span><span class="cls_007">InitializeComponent</span><span class="cls_004"> method is called.</span></div>
<div style="position:absolute;left:52.98px;top:717.75px" class="cls_007"><span class="cls_007">MouseLeftButtonDown += (o, e) => DragMove();</span></div>
<div style="position:absolute;left:5.00px;top:738.00px" class="cls_004"><span class="cls_004">This </span><span class="cls_007">DragMove</span><span class="cls_004"> method is declared within the </span><span class="cls_007">Window</span><span class="cls_004"> class and enables us to click and drag</span></div>
<div style="position:absolute;left:5.00px;top:756.00px" class="cls_004"><span class="cls_004">the window from anywhere within its bounds. We could easily recreate the normal window</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:229372px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background288.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">functionality of only being able to move the window from the title bar by adding our own title</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">bar and attaching this anonymous event handler to that object's </span><span class="cls_007">MouseLeftButtonDown</span><span class="cls_004"> event</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">instead.</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">If we want our borderless window to be resizable, there is a </span><span class="cls_007">ResizeMode</span><span class="cls_004"> property in the</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_007"><span class="cls_007">Window</span><span class="cls_004"> class that provides us with a few options. One value that we can use with our</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">borderless window is the </span><span class="cls_007">CanResizeWithGrip</span><span class="cls_004"> value. This option adds a so-called resize</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">grip, specified by a triangular pattern of dots in the bottom right corner of the window, that</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">users can resize the window with.</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">If we set the </span><span class="cls_007">ResizeMode</span><span class="cls_004"> property to this value and set the background to a color that will</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">contrast with this resize grip, we will end with this visual output.</span></div>
<div style="position:absolute;left:5.00px;top:305.25px" class="cls_004"><span class="cls_004">However, we still have no way to close the window. For this, we could add our own button,</span></div>
<div style="position:absolute;left:5.00px;top:323.25px" class="cls_004"><span class="cls_004">or perhaps enable the window to be closed by pressing the escape key (</span><span class="cls_006"> </span><span class="cls_012">Esc</span><span class="cls_006"> </span><span class="cls_004">)</span><span class="cls_006">,</span><span class="cls_004"> or some</span></div>
<div style="position:absolute;left:5.00px;top:342.00px" class="cls_004"><span class="cls_004">other key on the keyboard. Either way, whatever the trigger, closing the window is a simple</span></div>
<div style="position:absolute;left:5.00px;top:360.00px" class="cls_004"><span class="cls_004">matter of calling the window's </span><span class="cls_007">Close</span><span class="cls_004"> method.</span></div>
<div style="position:absolute;left:5.00px;top:378.00px" class="cls_004"><span class="cls_004">Rather than implementing a replacement window chrome, which could be easily achieved</span></div>
<div style="position:absolute;left:5.00px;top:396.00px" class="cls_004"><span class="cls_004">with a few borders, let's focus on developing a borderless window with an irregular shape,</span></div>
<div style="position:absolute;left:5.00px;top:414.00px" class="cls_004"><span class="cls_004">that we could use to popup helpful information for the users. Ordinarily, we would need to</span></div>
<div style="position:absolute;left:5.00px;top:432.00px" class="cls_004"><span class="cls_004">set the window's background to transparent to hide it, but we will be replacing its control</span></div>
<div style="position:absolute;left:5.00px;top:450.00px" class="cls_004"><span class="cls_004">template, so we don't need to do this.</span></div>
<div style="position:absolute;left:5.00px;top:468.00px" class="cls_004"><span class="cls_004">For this example, we don't need a resize grip either, so let's set the </span><span class="cls_007">ResizeMode</span><span class="cls_004"> property to</span></div>
<div style="position:absolute;left:5.00px;top:486.00px" class="cls_007"><span class="cls_007">NoResize</span><span class="cls_004">. We also have no need to move this callout window by mouse, so we don't need</span></div>
<div style="position:absolute;left:5.00px;top:504.00px" class="cls_004"><span class="cls_004">to add the anonymous event handler that calls the </span><span class="cls_007">DragMove</span><span class="cls_004"> method.</span></div>
<div style="position:absolute;left:5.00px;top:522.00px" class="cls_004"><span class="cls_004">As this window will only offer information to the user, we should also set a few other</span></div>
<div style="position:absolute;left:5.00px;top:540.00px" class="cls_004"><span class="cls_004">window properties. One important property to set is the </span><span class="cls_007">ShowInTaskbar</span><span class="cls_004"> property, which</span></div>
<div style="position:absolute;left:5.00px;top:558.00px" class="cls_004"><span class="cls_004">specifies whether the application icon should appear in the Windows Taskbar, or not. As this</span></div>
<div style="position:absolute;left:5.00px;top:576.00px" class="cls_004"><span class="cls_004">window will be an integral part of our main application, we set this property to </span><span class="cls_007">false</span><span class="cls_004">, so</span></div>
<div style="position:absolute;left:5.00px;top:594.00px" class="cls_004"><span class="cls_004">that its icon will be hidden.</span></div>
<div style="position:absolute;left:5.00px;top:612.00px" class="cls_004"><span class="cls_004">Another useful property for this situation is the </span><span class="cls_007">WindowStartupLocation</span><span class="cls_004"> property, which</span></div>
<div style="position:absolute;left:5.00px;top:630.00px" class="cls_004"><span class="cls_004">enables the window to be positioned using the </span><span class="cls_007">Window.Top</span><span class="cls_004"> and </span><span class="cls_007">Window.Left</span><span class="cls_004"> properties. In</span></div>
<div style="position:absolute;left:5.00px;top:648.00px" class="cls_004"><span class="cls_004">this way, the callout window can be programmatically positioned on screen anywhere that it</span></div>
<div style="position:absolute;left:5.00px;top:666.00px" class="cls_004"><span class="cls_004">is needed. Before continuing any further, let's see the code for this window.</span></div>
<div style="position:absolute;left:52.98px;top:689.25px" class="cls_007"><span class="cls_007"><Window</span></div>
<div style="position:absolute;left:52.98px;top:702.75px" class="cls_007"><span class="cls_007">x:Class="CompanyName.ApplicationName.Views.Controls.CalloutWindow"</span></div>
<div style="position:absolute;left:67.97px;top:716.25px" class="cls_007"><span class="cls_007">xmlns="</span><A HREF="http://schemas.microsoft.com/winfx/2006/xaml/presentation"/">http://schemas.microsoft.com/winfx/2006/xaml/presentation"</A> </div>
<div style="position:absolute;left:67.97px;top:729.75px" class="cls_007"><span class="cls_007">xmlns:x="</span><A HREF="http://schemas.microsoft.com/winfx/2006/xaml"/">http://schemas.microsoft.com/winfx/2006/xaml"</A> </div>
<div style="position:absolute;left:67.97px;top:743.25px" class="cls_007"><span class="cls_007">xmlns:mc="</span><A HREF="http://schemas.openxmlformats.org/markup-/">http://schemas.openxmlformats.org/markup-</A> </div>
<div style="position:absolute;left:52.98px;top:756.75px" class="cls_007"><span class="cls_007">compatibility/2006"</span></div>
<div style="position:absolute;left:67.97px;top:770.25px" class="cls_007"><span class="cls_007">xmlns:d="</span><A HREF="http://schemas.microsoft.com/expression/blend/2008"/">http://schemas.microsoft.com/expression/blend/2008"</A> </div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:230174px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background289.jpg" width=612 height=792></div>
<div style="position:absolute;left:67.97px;top:3.00px" class="cls_007"><span class="cls_007">xmlns:Controls=</span></div>
<div style="position:absolute;left:82.97px;top:16.50px" class="cls_007"><span class="cls_007">"clr-namespace:CompanyName.ApplicationName.Views.Controls"</span></div>
<div style="position:absolute;left:67.97px;top:30.00px" class="cls_007"><span class="cls_007">mc:Ignorable="d" d:DesignHeight="150" d:DesignWidth="300"</span></div>
<div style="position:absolute;left:82.97px;top:43.50px" class="cls_007"><span class="cls_007">WindowStartupLocation="Manual"></span></div>
<div style="position:absolute;left:67.97px;top:57.00px" class="cls_007"><span class="cls_007"><Window.Resources></span></div>
<div style="position:absolute;left:82.97px;top:70.50px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type Controls:CalloutWindow}"></span></div>
<div style="position:absolute;left:97.96px;top:84.00px" class="cls_007"><span class="cls_007"><Setter Property="ShowInTaskbar" Value="False" /></span></div>
<div style="position:absolute;left:97.96px;top:97.50px" class="cls_007"><span class="cls_007"><Setter Property="WindowStyle" Value="None" /></span></div>
<div style="position:absolute;left:97.96px;top:111.00px" class="cls_007"><span class="cls_007"><Setter Property="AllowsTransparency" Value="True" /></span></div>
<div style="position:absolute;left:97.96px;top:124.50px" class="cls_007"><span class="cls_007"><Setter Property="ResizeMode" Value="NoResize" /></span></div>
<div style="position:absolute;left:97.96px;top:138.00px" class="cls_007"><span class="cls_007"><Setter Property="Template"></span></div>
<div style="position:absolute;left:112.96px;top:151.50px" class="cls_007"><span class="cls_007"><Setter.Value></span></div>
<div style="position:absolute;left:127.95px;top:165.00px" class="cls_007"><span class="cls_007"><ControlTemplate TargetType="{x:Type</span></div>
<div style="position:absolute;left:52.98px;top:178.50px" class="cls_007"><span class="cls_007">Controls:CalloutWindow}"></span></div>
<div style="position:absolute;left:142.94px;top:192.00px" class="cls_007"><span class="cls_007"><Grid Margin="0,0,0,12"></span></div>
<div style="position:absolute;left:157.94px;top:205.50px" class="cls_007"><span class="cls_007"><Grid.ColumnDefinitions></span></div>
<div style="position:absolute;left:172.93px;top:219.00px" class="cls_007"><span class="cls_007"><ColumnDefinition Width="*" /></span></div>
<div style="position:absolute;left:172.93px;top:232.50px" class="cls_007"><span class="cls_007"><ColumnDefinition Width="5*" /></span></div>
<div style="position:absolute;left:157.94px;top:246.00px" class="cls_007"><span class="cls_007"></Grid.ColumnDefinitions></span></div>
<div style="position:absolute;left:157.94px;top:259.50px" class="cls_007"><span class="cls_007"><Path Grid.ColumnSpan="2"</span></div>
<div style="position:absolute;left:172.93px;top:273.00px" class="cls_007"><span class="cls_007">Fill="{TemplateBinding Background}"</span></div>
<div style="position:absolute;left:172.93px;top:286.50px" class="cls_007"><span class="cls_007">Stroke="{TemplateBinding BorderBrush}"</span></div>
<div style="position:absolute;left:172.93px;top:300.00px" class="cls_007"><span class="cls_007">StrokeThickness="2" Stretch="Fill"></span></div>
<div style="position:absolute;left:172.93px;top:313.50px" class="cls_007"><span class="cls_007"><Path.Data></span></div>
<div style="position:absolute;left:187.92px;top:327.00px" class="cls_007"><span class="cls_007"><CombinedGeometry GeometryCombineMode="Union"></span></div>
<div style="position:absolute;left:202.92px;top:340.50px" class="cls_007"><span class="cls_007"><CombinedGeometry.Geometry1></span></div>
<div style="position:absolute;left:217.91px;top:354.00px" class="cls_007"><span class="cls_007"><PathGeometry></span></div>
<div style="position:absolute;left:232.91px;top:367.50px" class="cls_007"><span class="cls_007"><PathFigure StartPoint="0,60"></span></div>
<div style="position:absolute;left:247.90px;top:381.00px" class="cls_007"><span class="cls_007"><LineSegment Point="50,45" /></span></div>
<div style="position:absolute;left:247.90px;top:394.50px" class="cls_007"><span class="cls_007"><LineSegment Point="50,75" /></span></div>
<div style="position:absolute;left:232.91px;top:408.00px" class="cls_007"><span class="cls_007"></PathFigure></span></div>
<div style="position:absolute;left:217.91px;top:421.50px" class="cls_007"><span class="cls_007"></PathGeometry></span></div>
<div style="position:absolute;left:202.92px;top:435.00px" class="cls_007"><span class="cls_007"></CombinedGeometry.Geometry1></span></div>
<div style="position:absolute;left:202.92px;top:448.50px" class="cls_007"><span class="cls_007"><CombinedGeometry.Geometry2></span></div>
<div style="position:absolute;left:217.91px;top:462.00px" class="cls_007"><span class="cls_007"><RectangleGeometry RadiusX="20" RadiusY="20"</span></div>
<div style="position:absolute;left:232.91px;top:475.50px" class="cls_007"><span class="cls_007">Rect="50,0,250,150" /></span></div>
<div style="position:absolute;left:202.92px;top:489.00px" class="cls_007"><span class="cls_007"></CombinedGeometry.Geometry2></span></div>
<div style="position:absolute;left:187.92px;top:502.50px" class="cls_007"><span class="cls_007"></CombinedGeometry></span></div>
<div style="position:absolute;left:172.93px;top:516.00px" class="cls_007"><span class="cls_007"></Path.Data></span></div>
<div style="position:absolute;left:157.94px;top:529.50px" class="cls_007"><span class="cls_007"></Path></span></div>
<div style="position:absolute;left:157.94px;top:543.00px" class="cls_007"><span class="cls_007"><ContentPresenter Grid.Column="1"</span></div>
<div style="position:absolute;left:172.93px;top:556.50px" class="cls_007"><span class="cls_007">Content="{TemplateBinding Content}"</span></div>
<div style="position:absolute;left:172.93px;top:570.00px" class="cls_007"><span class="cls_007">HorizontalAlignment="{TemplateBinding</span></div>
<div style="position:absolute;left:172.93px;top:583.50px" class="cls_007"><span class="cls_007">HorizontalContentAlignment}"</span></div>
<div style="position:absolute;left:172.93px;top:597.00px" class="cls_007"><span class="cls_007">VerticalAlignment="{TemplateBinding</span></div>
<div style="position:absolute;left:172.93px;top:610.50px" class="cls_007"><span class="cls_007">VerticalContentAlignment}"</span></div>
<div style="position:absolute;left:172.93px;top:624.00px" class="cls_007"><span class="cls_007">Margin="{TemplateBinding Padding}"></span></div>
<div style="position:absolute;left:172.93px;top:637.50px" class="cls_007"><span class="cls_007"><ContentPresenter.Resources></span></div>
<div style="position:absolute;left:187.92px;top:651.00px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type TextBlock}"></span></div>
<div style="position:absolute;left:202.92px;top:664.50px" class="cls_007"><span class="cls_007"><Setter Property="TextWrapping" Value="Wrap" /></span></div>
<div style="position:absolute;left:187.92px;top:678.00px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:172.93px;top:691.50px" class="cls_007"><span class="cls_007"></ContentPresenter.Resources></span></div>
<div style="position:absolute;left:157.94px;top:705.00px" class="cls_007"><span class="cls_007"></ContentPresenter></span></div>
<div style="position:absolute;left:157.94px;top:718.50px" class="cls_007"><span class="cls_007"><Grid.Effect></span></div>
<div style="position:absolute;left:172.93px;top:732.00px" class="cls_007"><span class="cls_007"><DropShadowEffect Color="Black"</span></div>
<div style="position:absolute;left:187.92px;top:745.50px" class="cls_007"><span class="cls_007">Direction="270" ShadowDepth="7" Opacity="0.3" /></span></div>
<div style="position:absolute;left:157.94px;top:759.00px" class="cls_007"><span class="cls_007"></Grid.Effect></span></div>
<div style="position:absolute;left:142.94px;top:772.50px" class="cls_007"><span class="cls_007"></Grid></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:230976px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background290.jpg" width=612 height=792></div>
<div style="position:absolute;left:127.95px;top:3.00px" class="cls_007"><span class="cls_007"></ControlTemplate></span></div>
<div style="position:absolute;left:112.96px;top:16.50px" class="cls_007"><span class="cls_007"></Setter.Value></span></div>
<div style="position:absolute;left:97.96px;top:30.00px" class="cls_007"><span class="cls_007"></Setter></span></div>
<div style="position:absolute;left:82.97px;top:43.50px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:67.97px;top:57.00px" class="cls_007"><span class="cls_007"></Window.Resources></span></div>
<div style="position:absolute;left:52.98px;top:70.50px" class="cls_007"><span class="cls_007"></Window></span></div>
<div style="position:absolute;left:5.00px;top:103.50px" class="cls_004"><span class="cls_004">While this example is not overly long, there is a lot to discuss here. In order to clarify the</span></div>
<div style="position:absolute;left:5.00px;top:121.50px" class="cls_004"><span class="cls_004">situation somewhat, let's also see the code behind before we examine this code:</span></div>
<div style="position:absolute;left:52.98px;top:144.75px" class="cls_007"><span class="cls_007">using System.Windows;</span></div>
<div style="position:absolute;left:52.98px;top:158.25px" class="cls_007"><span class="cls_007">using System.Windows.Media;</span></div>
<div style="position:absolute;left:52.98px;top:185.25px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.Views.Controls</span></div>
<div style="position:absolute;left:52.98px;top:198.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:212.25px" class="cls_007"><span class="cls_007">public partial class CalloutWindow : Window</span></div>
<div style="position:absolute;left:67.97px;top:225.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:239.25px" class="cls_007"><span class="cls_007">static CalloutWindow()</span></div>
<div style="position:absolute;left:82.97px;top:252.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:266.25px" class="cls_007"><span class="cls_007">BorderBrushProperty.OverrideMetadata (typeof(CalloutWindow),</span></div>
<div style="position:absolute;left:112.96px;top:279.75px" class="cls_007"><span class="cls_007">new FrameworkPropertyMetadata(</span></div>
<div style="position:absolute;left:112.96px;top:293.25px" class="cls_007"><span class="cls_007">new SolidColorBrush(Color.FromArgb(255, 238, 156, 88))));</span></div>
<div style="position:absolute;left:97.96px;top:306.75px" class="cls_007"><span class="cls_007">HorizontalContentAlignmentProperty.OverrideMetadata(</span></div>
<div style="position:absolute;left:112.96px;top:320.25px" class="cls_007"><span class="cls_007">typeof(CalloutWindow),</span></div>
<div style="position:absolute;left:112.96px;top:333.75px" class="cls_007"><span class="cls_007">new FrameworkPropertyMetadata(HorizontalAlignment.Center));</span></div>
<div style="position:absolute;left:97.96px;top:347.25px" class="cls_007"><span class="cls_007">VerticalContentAlignmentProperty.OverrideMetadata(</span></div>
<div style="position:absolute;left:112.96px;top:360.75px" class="cls_007"><span class="cls_007">typeof(CalloutWindow),</span></div>
<div style="position:absolute;left:112.96px;top:374.25px" class="cls_007"><span class="cls_007">new FrameworkPropertyMetadata(VerticalAlignment.Center));</span></div>
<div style="position:absolute;left:82.97px;top:387.75px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:414.75px" class="cls_007"><span class="cls_007">public CalloutWindow()</span></div>
<div style="position:absolute;left:82.97px;top:428.25px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:441.75px" class="cls_007"><span class="cls_007">InitializeComponent();</span></div>
<div style="position:absolute;left:82.97px;top:455.25px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:482.25px" class="cls_007"><span class="cls_007">public new static readonly DependencyProperty</span></div>
<div style="position:absolute;left:52.98px;top:495.75px" class="cls_007"><span class="cls_007">BackgroundProperty =</span></div>
<div style="position:absolute;left:97.96px;top:509.25px" class="cls_007"><span class="cls_007">DependencyProperty.Register(nameof(Background),</span></div>
<div style="position:absolute;left:52.98px;top:522.75px" class="cls_007"><span class="cls_007">typeof(Brush),</span></div>
<div style="position:absolute;left:97.96px;top:536.25px" class="cls_007"><span class="cls_007">typeof(CalloutWindow),</span></div>
<div style="position:absolute;left:97.96px;top:549.75px" class="cls_007"><span class="cls_007">new PropertyMetadata(new LinearGradientBrush(Colors.White,</span></div>
<div style="position:absolute;left:97.96px;top:563.25px" class="cls_007"><span class="cls_007">Color.FromArgb(255, 250, 191, 143), 90)));</span></div>
<div style="position:absolute;left:82.97px;top:590.25px" class="cls_007"><span class="cls_007">public new Brush Background</span></div>
<div style="position:absolute;left:82.97px;top:603.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:617.25px" class="cls_007"><span class="cls_007">get { return (Brush)GetValue(BackgroundProperty); }</span></div>
<div style="position:absolute;left:97.96px;top:630.75px" class="cls_007"><span class="cls_007">set { SetValue(BackgroundProperty, value); }</span></div>
<div style="position:absolute;left:82.97px;top:644.25px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:657.75px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:671.25px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:704.25px" class="cls_004"><span class="cls_004">This code behind file is simpler than the XAML file, so let's quickly walk through it first. We</span></div>
<div style="position:absolute;left:5.00px;top:722.25px" class="cls_004"><span class="cls_004">added a static constructor in order to call the </span><span class="cls_007">OverrideMetadata</span><span class="cls_004"> method on a few pre-</span></div>
<div style="position:absolute;left:5.00px;top:740.25px" class="cls_004"><span class="cls_004">existing Dependency Properties. This enables us to override the default settings of these</span></div>
<div style="position:absolute;left:5.00px;top:758.25px" class="cls_004"><span class="cls_004">properties and we do this in a static constructor because we want to run this code just once</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:231778px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background291.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">per class and because it is called before any other constructor or method in the class.</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">In this constructor, we override the metadata for the </span><span class="cls_007">BorderBrush</span><span class="cls_004"> property, in order to set a</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">default border color for our callout window. We do the same for both the</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_007"><span class="cls_007">HorizontalContentAlignment</span><span class="cls_004"> and </span><span class="cls_007">VerticalContentAlignment</span><span class="cls_004"> properties to ensure that the</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">window content will be centered by default. By doing this, we are re-using these existing</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">properties.</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">However, we can also totally replace the pre-existing properties. As an example, we've</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">replaced the </span><span class="cls_007">Background</span><span class="cls_004"> property to paint our callout background. In this case, we declare</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">our own </span><span class="cls_007">Background</span><span class="cls_004"> property, specified by the </span><span class="cls_007">new</span><span class="cls_004"> keyword, and set its own default brush</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">color. We then use that to paint the background of our callout shape, although we could just</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">as easily add another setter into our style to reuse the original </span><span class="cls_007">Background</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">Looking at the XAML code now, we can see the </span><span class="cls_007">WindowStartupLocation</span><span class="cls_004"> property set in the</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_007"><span class="cls_007">Window</span><span class="cls_004"> declaration, followed by a style in the window's </span><span class="cls_007">Resources</span><span class="cls_004"> section. In this style, we</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">set the aforementioned properties and define the window's control template. Inside the</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_007"><span class="cls_007">ControlTemplate</span><span class="cls_004"> object, we define a </span><span class="cls_007">Grid</span><span class="cls_004"> panel. We'll return to this later, but for now, note</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">that there is a nine pixel margin set on the bottom of the panel.</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">Next, note that the panel has two star-sized </span><span class="cls_007">ColumnDefinition</span><span class="cls_004"> elements declared, one with</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">a width of </span><span class="cls_007">*</span><span class="cls_004"> and another with a width of </span><span class="cls_007">5*</span><span class="cls_004">. If we add these together, we end with a total</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_004"><span class="cls_004">width of six equal divisions. This means that the first column will be one sixth of the total</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_004"><span class="cls_004">width of the window and the second column will take up the remaining five sixths. We will</span></div>
<div style="position:absolute;left:5.00px;top:363.75px" class="cls_004"><span class="cls_004">soon see why this is set as it is.</span></div>
<div style="position:absolute;left:5.00px;top:381.75px" class="cls_004"><span class="cls_004">Inside the </span><span class="cls_007">Grid</span><span class="cls_004"> panel, we first declare the </span><span class="cls_007">Path</span><span class="cls_004"> element that is used to define the shape of</span></div>
<div style="position:absolute;left:5.00px;top:399.75px" class="cls_004"><span class="cls_004">our callout. We set the </span><span class="cls_007">Grid.ColumnSpan</span><span class="cls_004"> property on it to </span><span class="cls_007">2</span><span class="cls_004">, to ensure that it takes all of the</span></div>
<div style="position:absolute;left:5.00px;top:417.75px" class="cls_004"><span class="cls_004">space of the parent window. Next, we set our new </span><span class="cls_007">Background</span><span class="cls_004"> property to the </span><span class="cls_007">Fill</span></div>
<div style="position:absolute;left:5.00px;top:435.75px" class="cls_004"><span class="cls_004">property, so that users of our window can set its </span><span class="cls_007">Background</span><span class="cls_004"> property and have that brush</span></div>
<div style="position:absolute;left:5.00px;top:453.75px" class="cls_004"><span class="cls_004">paint just the background of our path.</span></div>
<div style="position:absolute;left:5.00px;top:471.75px" class="cls_004"><span class="cls_004">We also set the </span><span class="cls_007">Stroke</span><span class="cls_004"> property of the </span><span class="cls_007">Path</span><span class="cls_004"> element to the overridden </span><span class="cls_007">BorderBrush</span></div>
<div style="position:absolute;left:5.00px;top:489.75px" class="cls_004"><span class="cls_004">property and although we didn't, we could have exposed the </span><span class="cls_007">StrokeThickness</span><span class="cls_004"> property by</span></div>
<div style="position:absolute;left:5.00px;top:507.75px" class="cls_004"><span class="cls_004">declaring another Dependency Property. Note that we use </span><span class="cls_007">TemplateBinding</span><span class="cls_004"> elements to</span></div>
<div style="position:absolute;left:5.00px;top:525.75px" class="cls_004"><span class="cls_004">access the properties of the window, as they are the most efficient in this particular case.</span></div>
<div style="position:absolute;left:5.00px;top:543.75px" class="cls_004"><span class="cls_004">Take special note of the </span><span class="cls_007">Path.Stretch</span><span class="cls_004"> property, which we have set to </span><span class="cls_007">Fill</span><span class="cls_004"> and defines how</span></div>
<div style="position:absolute;left:5.00px;top:561.75px" class="cls_004"><span class="cls_004">the shape should fill the space that it is provided with. Using this </span><span class="cls_007">Fill</span><span class="cls_004"> value specifies that</span></div>
<div style="position:absolute;left:5.00px;top:579.75px" class="cls_004"><span class="cls_004">the content should fill all of the available space, rather than preserve its originally defined</span></div>
<div style="position:absolute;left:5.00px;top:597.75px" class="cls_004"><span class="cls_004">aspect ratio. However, if we want to preserve the aspect ratio, then we can change this</span></div>
<div style="position:absolute;left:5.00px;top:615.75px" class="cls_004"><span class="cls_004">property to the </span><span class="cls_007">Uniform</span><span class="cls_004"> value instead.</span></div>
<div style="position:absolute;left:5.00px;top:633.75px" class="cls_004"><span class="cls_004">The most important part of the path is found in the </span><span class="cls_007">Path.Data</span><span class="cls_004"> section. This defines the</span></div>
<div style="position:absolute;left:5.00px;top:651.75px" class="cls_004"><span class="cls_004">shape of the rendered path and like our layered background example, we utilize a</span></div>
<div style="position:absolute;left:5.00px;top:669.75px" class="cls_007"><span class="cls_007">CombinedGeometry</span><span class="cls_004"> element here to combine two separate geometries. Unlike the previous</span></div>
<div style="position:absolute;left:5.00px;top:687.75px" class="cls_004"><span class="cls_004">example, here we use a </span><span class="cls_007">GeometryCombineMode</span><span class="cls_004"> value of </span><span class="cls_007">Union</span><span class="cls_004">, which renders the output of</span></div>
<div style="position:absolute;left:5.00px;top:705.75px" class="cls_004"><span class="cls_004">both geometry shapes together.</span></div>
<div style="position:absolute;left:5.00px;top:723.75px" class="cls_004"><span class="cls_004">In the </span><span class="cls_007">CombinedGeometry.Geometry1</span><span class="cls_004"> element, we declare a </span><span class="cls_007">PathGeometry</span><span class="cls_004"> object with a</span></div>
<div style="position:absolute;left:5.00px;top:741.75px" class="cls_007"><span class="cls_007">PathFigure</span><span class="cls_004"> element that has a starting point and two </span><span class="cls_007">LineSegment</span><span class="cls_004"> elements. Together with</span></div>
<div style="position:absolute;left:5.00px;top:759.75px" class="cls_004"><span class="cls_004">the starting point, these two elements form the triangle section of our callout, that points to</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:232580px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background292.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">the area on screen that our window's information relates to. Note that this triangle is fifty</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">pixels wide in the path.</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">In the </span><span class="cls_007">CombinedGeometry.Geometry2</span><span class="cls_004"> element, we declare a </span><span class="cls_007">RectangleGeometry</span><span class="cls_004"> object, with</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">its size specified by the </span><span class="cls_007">Rect</span><span class="cls_004"> property and the size of its rounded corners being specified by</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">RadiusX</span><span class="cls_004"> and </span><span class="cls_007">RadiusY</span><span class="cls_004"> properties. The rectangle is positioned fifty pixels away from the</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">left edge and its width is two hundred and fifty pixels wide.</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">The overall area taken up by the rectangle and the triangle is therefore three hundred</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">pixels. One sixth of three hundred is fifty and this is how wide the triangle in our shape is.</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">This explains why our first </span><span class="cls_007">Grid</span><span class="cls_004"> column is set to take one sixth of the total space.</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">After the </span><span class="cls_007">Path</span><span class="cls_004"> object, we declare the </span><span class="cls_007">ContentPresenter</span><span class="cls_004"> element that is required to output</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">the actual content of the window and set it to be in the second column of the panel. In short,</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">this column is used to position the </span><span class="cls_007">ContentPresenter</span><span class="cls_004"> element directly over the rectangle</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">section of our shape, avoiding the triangular section.</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">In the </span><span class="cls_007">ContentPresenter</span><span class="cls_004"> element, we data bind several positional properties to the relevant</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">properties of the window using </span><span class="cls_007">TemplateBinding</span><span class="cls_004"> elements. We also data bind its </span><span class="cls_007">Content</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">property to the </span><span class="cls_007">Content</span><span class="cls_004"> property of the window using another </span><span class="cls_007">TemplateBinding</span><span class="cls_004"> element.</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">Note that we could have declared our UI controls directly within the </span><span class="cls_007">Window</span><span class="cls_004"> control.</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">However, had we done that, then we would not be able to data bind to its </span><span class="cls_007">Content</span><span class="cls_004"> property</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_004"><span class="cls_004">in this way, as setting it externally would replace all of our declared XAML controls,</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_004"><span class="cls_004">including the </span><span class="cls_007">ContentPresenter</span><span class="cls_004"> object. By providing a new template, we are totally</span></div>
<div style="position:absolute;left:5.00px;top:363.75px" class="cls_004"><span class="cls_004">overriding the default behavior of the window.</span></div>
<div style="position:absolute;left:5.00px;top:381.75px" class="cls_004"><span class="cls_004">Also note that we have declared a style in the </span><span class="cls_007">Resources</span><span class="cls_004"> section of the </span><span class="cls_007">ContentPresenter</span></div>
<div style="position:absolute;left:5.00px;top:399.75px" class="cls_004"><span class="cls_004">element. This style has been declared without the </span><span class="cls_007">x:Key</span><span class="cls_004"> directive, so that it will be implicitly</span></div>
<div style="position:absolute;left:5.00px;top:417.75px" class="cls_004"><span class="cls_004">applied to all </span><span class="cls_007">TextBlock</span><span class="cls_004"> objects within scope, specifically to affect the </span><span class="cls_007">TextBlock</span><span class="cls_004"> objects</span></div>
<div style="position:absolute;left:5.00px;top:435.75px" class="cls_004"><span class="cls_004">that the </span><span class="cls_007">ContentPresenter</span><span class="cls_004"> element will automatically generate for string values, while not</span></div>
<div style="position:absolute;left:5.00px;top:453.75px" class="cls_004"><span class="cls_004">affecting others.</span></div>
<div style="position:absolute;left:5.00px;top:471.75px" class="cls_004"><span class="cls_004">The style sets the </span><span class="cls_007">TextBlock.TextWrapping</span><span class="cls_004"> property to the </span><span class="cls_007">Wrap</span><span class="cls_004"> member of the</span></div>
<div style="position:absolute;left:5.00px;top:489.75px" class="cls_007"><span class="cls_007">TextWrapping</span><span class="cls_004"> enumeration, which has the effect of wrapping long text lines onto the</span></div>
<div style="position:absolute;left:5.00px;top:507.75px" class="cls_004"><span class="cls_004">following lines. The default setting is </span><span class="cls_007">NoWrap</span><span class="cls_004">, which would result in long strings not being</span></div>
<div style="position:absolute;left:5.00px;top:525.75px" class="cls_004"><span class="cls_004">fully displayed in our window.</span></div>
<div style="position:absolute;left:5.00px;top:543.75px" class="cls_004"><span class="cls_004">Finally, we come to the end of the XAML example and find a </span><span class="cls_007">DropShadowEffect</span><span class="cls_004"> object set</span></div>
<div style="position:absolute;left:5.00px;top:561.75px" class="cls_004"><span class="cls_004">as the </span><span class="cls_007">Effect</span><span class="cls_004"> property of the </span><span class="cls_007">Grid</span><span class="cls_004"> panel. As with all shadow effects, we set the </span><span class="cls_007">Color</span></div>
<div style="position:absolute;left:5.00px;top:579.75px" class="cls_004"><span class="cls_004">property to black and the </span><span class="cls_007">Opacity</span><span class="cls_004"> property to a value less or equal to </span><span class="cls_007">0.5</span><span class="cls_004">. The </span><span class="cls_007">Direction</span></div>
<div style="position:absolute;left:5.00px;top:597.75px" class="cls_004"><span class="cls_004">property is set to </span><span class="cls_007">270</span><span class="cls_004">, which produces a shadow that lies directly underneath our callout</span></div>
<div style="position:absolute;left:5.00px;top:615.75px" class="cls_004"><span class="cls_004">shape.</span></div>
<div style="position:absolute;left:5.00px;top:633.75px" class="cls_004"><span class="cls_004">Note that we set the </span><span class="cls_007">ShadowDepth</span><span class="cls_004"> property to a value of </span><span class="cls_007">7</span><span class="cls_004">. Now, do you remember the</span></div>
<div style="position:absolute;left:5.00px;top:651.75px" class="cls_004"><span class="cls_004">bottom margin that was set on the grid? That was set to a value just above this value and</span></div>
<div style="position:absolute;left:5.00px;top:669.75px" class="cls_004"><span class="cls_004">was to ensure that enough space was left in the window to display our shadow underneath</span></div>
<div style="position:absolute;left:5.00px;top:687.75px" class="cls_004"><span class="cls_004">our callout shape. Without this, the shadow would sit outside the bounding box of the</span></div>
<div style="position:absolute;left:5.00px;top:705.75px" class="cls_004"><span class="cls_004">window and not be displayed.</span></div>
<div style="position:absolute;left:5.00px;top:723.75px" class="cls_004"><span class="cls_004">If we had set a different value for the </span><span class="cls_007">Direction</span><span class="cls_004"> property, then we would need to adjust the</span></div>
<div style="position:absolute;left:5.00px;top:741.75px" class="cls_007"><span class="cls_007">Grid</span><span class="cls_004"> panel's margin to ensure that it left enough space around the window to display the</span></div>
<div style="position:absolute;left:5.00px;top:759.75px" class="cls_004"><span class="cls_004">shadow in its new location. Let's now take a look at how we could use our new window:</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:233382px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background293.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:9.00px" class="cls_007"><span class="cls_007">CalloutWindow calloutWindow = new CalloutWindow();</span></div>
<div style="position:absolute;left:52.98px;top:22.50px" class="cls_007"><span class="cls_007">calloutWindow.Width = 225;</span></div>
<div style="position:absolute;left:52.98px;top:36.00px" class="cls_007"><span class="cls_007">calloutWindow.Height = 120;</span></div>
<div style="position:absolute;left:52.98px;top:49.50px" class="cls_007"><span class="cls_007">calloutWindow.FontSize = 18;</span></div>
<div style="position:absolute;left:52.98px;top:63.00px" class="cls_007"><span class="cls_007">calloutWindow.Padding = new Thickness(20);</span></div>
<div style="position:absolute;left:52.98px;top:76.50px" class="cls_007"><span class="cls_007">calloutWindow.Content = "Please fill in the first line of your</span></div>
<div style="position:absolute;left:52.98px;top:90.00px" class="cls_007"><span class="cls_007">address.";</span></div>
<div style="position:absolute;left:52.98px;top:103.50px" class="cls_007"><span class="cls_007">calloutWindow.Show();</span></div>
<div style="position:absolute;left:5.00px;top:123.75px" class="cls_004"><span class="cls_004">Running this code from a suitable location would result in the following rendered output:</span></div>
<div style="position:absolute;left:5.00px;top:276.75px" class="cls_004"><span class="cls_004">In our window-showing code, we set a string to the </span><span class="cls_007">Content</span><span class="cls_004"> property of the window.</span></div>
<div style="position:absolute;left:5.00px;top:294.75px" class="cls_004"><span class="cls_004">However, this property is of type </span><span class="cls_007">object</span><span class="cls_004"> and so we can add any object as its value. In the</span></div>
<div style="position:absolute;left:5.00px;top:312.75px" class="cls_004"><span class="cls_004">same way that we set our View Model instances to the </span><span class="cls_007">Content</span><span class="cls_004"> property of a</span></div>
<div style="position:absolute;left:5.00px;top:330.75px" class="cls_007"><span class="cls_007">ContentControl</span><span class="cls_004"> earlier in this book, we can also do that with our window.</span></div>
<div style="position:absolute;left:5.00px;top:348.75px" class="cls_004"><span class="cls_004">Given a suitable </span><span class="cls_007">DataTemplate</span><span class="cls_004"> that defines some UI for a particular custom object type, we</span></div>
<div style="position:absolute;left:5.00px;top:366.75px" class="cls_004"><span class="cls_004">could set an instance of that object to our window's </span><span class="cls_007">Content</span><span class="cls_004"> property and have the controls</span></div>
<div style="position:absolute;left:5.00px;top:384.75px" class="cls_004"><span class="cls_004">from that template rendered within our callout window, so we are not restricted to only</span></div>
<div style="position:absolute;left:5.00px;top:402.75px" class="cls_004"><span class="cls_004">using strings here. Let's use a previous example:</span></div>
<div style="position:absolute;left:52.98px;top:426.00px" class="cls_007"><span class="cls_007">calloutWindow.DataContext = new UsersViewModel();</span></div>
<div style="position:absolute;left:5.00px;top:446.25px" class="cls_004"><span class="cls_004">With a few slight adjustments to our </span><span class="cls_007">calloutWindow</span><span class="cls_004"> dimension properties, we would see</span></div>
<div style="position:absolute;left:5.00px;top:464.25px" class="cls_004"><span class="cls_004">this:</span></div>
<div style="position:absolute;left:5.00px;top:641.26px" class="cls_011"><span class="cls_011">Visualizing data</span></div>
<div style="position:absolute;left:5.00px;top:671.25px" class="cls_004"><span class="cls_004">While there are a number of pre-existing graph controls and third party data visualization</span></div>
<div style="position:absolute;left:5.00px;top:689.25px" class="cls_004"><span class="cls_004">controls available in WPF, we can create our own relatively easily. Expressing data in</span></div>
<div style="position:absolute;left:5.00px;top:707.25px" class="cls_004"><span class="cls_004">textual terms alone, while generally acceptable, is not optimal. Breaking the norm in an</span></div>
<div style="position:absolute;left:5.00px;top:725.25px" class="cls_004"><span class="cls_004">application always makes that application stand out from the rest that strictly adhere to the</span></div>
<div style="position:absolute;left:5.00px;top:743.25px" class="cls_004"><span class="cls_004">standard.</span></div>
<div style="position:absolute;left:5.00px;top:761.25px" class="cls_004"><span class="cls_004">As an example, imagine a simple situation, where we have a dashboard that visualizes the</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:234184px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background294.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">number of work tasks that have come in and the number that have been completed. We</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">could just output the numbers in a big, bold font, but that would be the normal kind of</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">output. What about if we visualized each number as a shape, with its size being specified by</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">the number?</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">Let's reuse our layering techniques from earlier and design some visually appealing</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">spheres, that grow in size depending upon a particular value. To do this, we can create</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">another custom control, with a </span><span class="cls_007">Value</span><span class="cls_004"> Dependency Property to data bind to. Let's first look</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">at the code of the </span><span class="cls_007">Sphere</span><span class="cls_004"> class:</span></div>
<div style="position:absolute;left:52.98px;top:153.00px" class="cls_007"><span class="cls_007">using System.Windows;</span></div>
<div style="position:absolute;left:52.98px;top:166.50px" class="cls_007"><span class="cls_007">using System.Windows.Controls;</span></div>
<div style="position:absolute;left:52.98px;top:180.00px" class="cls_007"><span class="cls_007">using System.Windows.Media;</span></div>
<div style="position:absolute;left:52.98px;top:193.50px" class="cls_007"><span class="cls_007">using System.Windows.Shapes;</span></div>
<div style="position:absolute;left:52.98px;top:207.00px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.CustomControls.Enums;</span></div>
<div style="position:absolute;left:52.98px;top:220.50px" class="cls_007"><span class="cls_007">using MediaColor = System.Windows.Media.Color;</span></div>
<div style="position:absolute;left:52.98px;top:247.50px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.CustomControls</span></div>
<div style="position:absolute;left:52.98px;top:261.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:274.50px" class="cls_007"><span class="cls_007">[TemplatePart(Name = "PART_Background", Type = typeof(Ellipse))]</span></div>
<div style="position:absolute;left:67.97px;top:288.00px" class="cls_007"><span class="cls_007">[TemplatePart(Name = "PART_Glow", Type = typeof(Ellipse))]</span></div>
<div style="position:absolute;left:67.97px;top:301.50px" class="cls_007"><span class="cls_007">public class Sphere : Control</span></div>
<div style="position:absolute;left:67.97px;top:315.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:328.50px" class="cls_007"><span class="cls_007">private RadialGradientBrush greenBackground =</span></div>
<div style="position:absolute;left:97.96px;top:342.00px" class="cls_007"><span class="cls_007">new RadialGradientBrush(new GradientStopCollection() {</span></div>
<div style="position:absolute;left:97.96px;top:355.50px" class="cls_007"><span class="cls_007">new GradientStop(MediaColor.FromRgb(0, 254, 0), 0),</span></div>
<div style="position:absolute;left:97.96px;top:369.00px" class="cls_007"><span class="cls_007">new GradientStop(MediaColor.FromRgb(1, 27, 0), 0.974) });</span></div>
<div style="position:absolute;left:82.97px;top:382.50px" class="cls_007"><span class="cls_007">private RadialGradientBrush greenGlow =</span></div>
<div style="position:absolute;left:97.96px;top:396.00px" class="cls_007"><span class="cls_007">new RadialGradientBrush(new GradientStopCollection() {</span></div>
<div style="position:absolute;left:97.96px;top:409.50px" class="cls_007"><span class="cls_007">new GradientStop(MediaColor.FromArgb(205, 67, 255, 46), 0),</span></div>
<div style="position:absolute;left:97.96px;top:423.00px" class="cls_007"><span class="cls_007">new GradientStop(MediaColor.FromArgb(102, 88, 254, 72),</span></div>
<div style="position:absolute;left:52.98px;top:436.50px" class="cls_007"><span class="cls_007">0.426),</span></div>
<div style="position:absolute;left:97.96px;top:450.00px" class="cls_007"><span class="cls_007">new GradientStop(MediaColor.FromArgb(0, 44, 191, 32), 1) });</span></div>
<div style="position:absolute;left:82.97px;top:463.50px" class="cls_007"><span class="cls_007">private RadialGradientBrush redBackground =</span></div>
<div style="position:absolute;left:97.96px;top:477.00px" class="cls_007"><span class="cls_007">new RadialGradientBrush(new GradientStopCollection() {</span></div>
<div style="position:absolute;left:97.96px;top:490.50px" class="cls_007"><span class="cls_007">new GradientStop(MediaColor.FromRgb(254, 0, 0), 0),</span></div>
<div style="position:absolute;left:97.96px;top:504.00px" class="cls_007"><span class="cls_007">new GradientStop(MediaColor.FromRgb(27, 0, 0), 0.974) });</span></div>
<div style="position:absolute;left:82.97px;top:517.50px" class="cls_007"><span class="cls_007">private RadialGradientBrush redGlow =</span></div>
<div style="position:absolute;left:97.96px;top:531.00px" class="cls_007"><span class="cls_007">new RadialGradientBrush(new GradientStopCollection() {</span></div>
<div style="position:absolute;left:97.96px;top:544.50px" class="cls_007"><span class="cls_007">new GradientStop(MediaColor.FromArgb(205, 255, 46, 46), 0),</span></div>
<div style="position:absolute;left:97.96px;top:558.00px" class="cls_007"><span class="cls_007">new GradientStop(MediaColor.FromArgb(102, 254, 72, 72),</span></div>
<div style="position:absolute;left:52.98px;top:571.50px" class="cls_007"><span class="cls_007">0.426),</span></div>
<div style="position:absolute;left:97.96px;top:585.00px" class="cls_007"><span class="cls_007">new GradientStop(MediaColor.FromArgb(0, 191, 32, 32), 1) });</span></div>
<div style="position:absolute;left:82.97px;top:612.00px" class="cls_007"><span class="cls_007">static Sphere()</span></div>
<div style="position:absolute;left:82.97px;top:625.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:639.00px" class="cls_007"><span class="cls_007">DefaultStyleKeyProperty.OverrideMetadata(typeof(Sphere),</span></div>
<div style="position:absolute;left:112.96px;top:652.50px" class="cls_007"><span class="cls_007">new FrameworkPropertyMetadata(typeof(Sphere)));</span></div>
<div style="position:absolute;left:82.97px;top:666.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:693.00px" class="cls_007"><span class="cls_007">public static readonly DependencyProperty ValueProperty =</span></div>
<div style="position:absolute;left:97.96px;top:706.50px" class="cls_007"><span class="cls_007">DependencyProperty.Register(nameof(Value), typeof(double),</span></div>
<div style="position:absolute;left:97.96px;top:720.00px" class="cls_007"><span class="cls_007">typeof(Sphere), new PropertyMetadata(50.0));</span></div>
<div style="position:absolute;left:82.97px;top:747.00px" class="cls_007"><span class="cls_007">public double Value</span></div>
<div style="position:absolute;left:82.97px;top:760.50px" class="cls_007"><span class="cls_007">{</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:234986px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background295.jpg" width=612 height=792></div>
<div style="position:absolute;left:97.96px;top:3.00px" class="cls_007"><span class="cls_007">get { return (double)GetValue(ValueProperty); }</span></div>
<div style="position:absolute;left:97.96px;top:16.50px" class="cls_007"><span class="cls_007">set { SetValue(ValueProperty, value); }</span></div>
<div style="position:absolute;left:82.97px;top:30.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:57.00px" class="cls_007"><span class="cls_007">public static readonly DependencyProperty ColorProperty =</span></div>
<div style="position:absolute;left:97.96px;top:70.50px" class="cls_007"><span class="cls_007">DependencyProperty.Register(nameof(Color),</span></div>
<div style="position:absolute;left:52.98px;top:84.00px" class="cls_007"><span class="cls_007">typeof(SphereColor),</span></div>
<div style="position:absolute;left:97.96px;top:97.50px" class="cls_007"><span class="cls_007">typeof(Sphere), new PropertyMetadata(SphereColor.Green,</span></div>
<div style="position:absolute;left:97.96px;top:111.00px" class="cls_007"><span class="cls_007">OnColorChanged));</span></div>
<div style="position:absolute;left:82.97px;top:138.00px" class="cls_007"><span class="cls_007">public SphereColor Color</span></div>
<div style="position:absolute;left:82.97px;top:151.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:165.00px" class="cls_007"><span class="cls_007">get { return (SphereColor)GetValue(ColorProperty); }</span></div>
<div style="position:absolute;left:97.96px;top:178.50px" class="cls_007"><span class="cls_007">set { SetValue(ColorProperty, value); }</span></div>
<div style="position:absolute;left:82.97px;top:192.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:219.00px" class="cls_007"><span class="cls_007">private static void OnColorChanged(DependencyObject</span></div>
<div style="position:absolute;left:97.96px;top:232.50px" class="cls_007"><span class="cls_007">dependencyObject, DependencyPropertyChangedEventArgs e)</span></div>
<div style="position:absolute;left:82.97px;top:246.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:259.50px" class="cls_007"><span class="cls_007">((Sphere)dependencyObject).SetEllipseColors();</span></div>
<div style="position:absolute;left:82.97px;top:273.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:300.00px" class="cls_007"><span class="cls_007">public override void OnApplyTemplate()</span></div>
<div style="position:absolute;left:82.97px;top:313.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:327.00px" class="cls_007"><span class="cls_007">SetEllipseColors();</span></div>
<div style="position:absolute;left:82.97px;top:340.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:367.50px" class="cls_007"><span class="cls_007">private void SetEllipseColors()</span></div>
<div style="position:absolute;left:82.97px;top:381.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:394.50px" class="cls_007"><span class="cls_007">Ellipse backgroundEllipse =</span></div>
<div style="position:absolute;left:112.96px;top:408.00px" class="cls_007"><span class="cls_007">GetTemplateChild("PART_Background") as Ellipse;</span></div>
<div style="position:absolute;left:97.96px;top:421.50px" class="cls_007"><span class="cls_007">Ellipse glowEllipse = GetTemplateChild("PART_Glow") as</span></div>
<div style="position:absolute;left:52.98px;top:435.00px" class="cls_007"><span class="cls_007">Ellipse;</span></div>
<div style="position:absolute;left:97.96px;top:448.50px" class="cls_007"><span class="cls_007">if (backgroundEllipse != null) backgroundEllipse.Fill =</span></div>
<div style="position:absolute;left:112.96px;top:462.00px" class="cls_007"><span class="cls_007">Color == SphereColor.Green ? greenBackground :</span></div>
<div style="position:absolute;left:52.98px;top:475.50px" class="cls_007"><span class="cls_007">redBackground;</span></div>
<div style="position:absolute;left:97.96px;top:489.00px" class="cls_007"><span class="cls_007">if (glowEllipse != null) glowEllipse.Fill =</span></div>
<div style="position:absolute;left:112.96px;top:502.50px" class="cls_007"><span class="cls_007">Color == SphereColor.Green ? greenGlow : redGlow;</span></div>
<div style="position:absolute;left:97.96px;top:516.00px" class="cls_007"><span class="cls_007">base.OnApplyTemplate();</span></div>
<div style="position:absolute;left:82.97px;top:529.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:543.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:556.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:576.75px" class="cls_004"><span class="cls_004">As this class will declare its own </span><span class="cls_007">Color</span><span class="cls_004"> property, we start by adding a </span><span class="cls_007">MediaColor</span><span class="cls_004"> using</span></div>
<div style="position:absolute;left:5.00px;top:594.75px" class="cls_004"><span class="cls_004">alias directive, which we'll just use as a shortcut to accessing the methods of</span></div>
<div style="position:absolute;left:5.00px;top:612.75px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">System.Windows.Media.Color</span><span class="cls_004"> class, when declaring the brushes that will be used in</span></div>
<div style="position:absolute;left:5.00px;top:630.75px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">Sphere</span><span class="cls_004"> class.</span></div>
<div style="position:absolute;left:5.00px;top:648.75px" class="cls_004"><span class="cls_004">From the class declaration, we can see that there are two named parts specified in</span></div>
<div style="position:absolute;left:5.00px;top:666.75px" class="cls_007"><span class="cls_007">TemplatePartAttribute</span><span class="cls_004"> attributes. These specify that the two mentioned </span><span class="cls_007">Ellipse</span><span class="cls_004"> elements</span></div>
<div style="position:absolute;left:5.00px;top:684.75px" class="cls_004"><span class="cls_004">are required in our control's template in the </span><span class="cls_007">Generic.xaml</span><span class="cls_004"> file. Inside the class, we define a</span></div>
<div style="position:absolute;left:5.00px;top:702.75px" class="cls_004"><span class="cls_004">number of </span><span class="cls_007">RadialGradientBrush</span><span class="cls_004"> resources to paint our spheres with.</span></div>
<div style="position:absolute;left:5.00px;top:720.75px" class="cls_004"><span class="cls_004">In the static constructor, we call the </span><span class="cls_007">OverrideMetadata</span><span class="cls_004"> method to let the Framework know</span></div>
<div style="position:absolute;left:5.00px;top:738.75px" class="cls_004"><span class="cls_004">where our control's default style is. We then see the declaration of the </span><span class="cls_007">Value</span><span class="cls_004"> and </span><span class="cls_007">Color</span></div>
<div style="position:absolute;left:5.00px;top:756.75px" class="cls_004"><span class="cls_004">Dependency Properties, with the </span><span class="cls_007">Color</span><span class="cls_004"> property's related </span><span class="cls_007">PropertyChangedCallback</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:235788px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background296.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">hander method.</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">In this </span><span class="cls_007">OnColorChanged</span><span class="cls_004"> method, we cast the </span><span class="cls_007">dependencyObject</span><span class="cls_004"> input parameter to an</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">instance of our </span><span class="cls_007">Sphere</span><span class="cls_004"> class and call its </span><span class="cls_007">SetEllipseColors</span><span class="cls_004"> method. In that method, we use</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">FrameworkElement.GetTemplateChild</span><span class="cls_004"> method to access the two main </span><span class="cls_007">Ellipse</span><span class="cls_004"> objects</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">from our </span><span class="cls_007">ControlTemplate</span><span class="cls_004"> element.</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">Remember that we must always check these objects for null, as our </span><span class="cls_007">ControlTemplate</span><span class="cls_004"> could</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">have been replaced with one that does not contain these ellipse elements. If they are not</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">null, we then set their </span><span class="cls_007">Fill</span><span class="cls_004"> properties to one of our brush resources using the ternary</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">operator and depending upon the value of our </span><span class="cls_007">Color</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">One alternative for creating this functionality would be to declare a Dependency Property of</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">type </span><span class="cls_007">Brush</span><span class="cls_004"> to data bind to each ellipse's </span><span class="cls_007">Fill</span><span class="cls_004"> property and to set the relevant brush</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">resources to these properties, instead of accessing the XAML elements directly. Before</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">viewing the control's default style, let's see the </span><span class="cls_007">SphereColor</span><span class="cls_004"> enumeration that is used by the</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_007"><span class="cls_007">Color</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:52.98px;top:261.00px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.CustomControls.Enums</span></div>
<div style="position:absolute;left:52.98px;top:274.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:288.00px" class="cls_007"><span class="cls_007">public enum SphereColor</span></div>
<div style="position:absolute;left:67.97px;top:301.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:315.00px" class="cls_007"><span class="cls_007">Green, Red</span></div>
<div style="position:absolute;left:67.97px;top:328.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:342.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:362.25px" class="cls_004"><span class="cls_004">As you can see, this is a simple affair and could be easily extended. Note that this</span></div>
<div style="position:absolute;left:5.00px;top:380.25px" class="cls_004"><span class="cls_004">enumeration has been declared within the </span><span class="cls_007">CustomControls</span><span class="cls_004"> namespace and project, so that</span></div>
<div style="position:absolute;left:5.00px;top:398.25px" class="cls_004"><span class="cls_004">the project is self-contained and can be reused in other applications without any external</span></div>
<div style="position:absolute;left:5.00px;top:416.25px" class="cls_004"><span class="cls_004">dependencies. Let's take a look at our control's default style from </span><span class="cls_007">Generic.xaml</span><span class="cls_004"> now.</span></div>
<div style="position:absolute;left:52.98px;top:439.50px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type CustomControls:Sphere}"></span></div>
<div style="position:absolute;left:67.97px;top:453.00px" class="cls_007"><span class="cls_007"><Setter Property="Template"></span></div>
<div style="position:absolute;left:82.97px;top:466.50px" class="cls_007"><span class="cls_007"><Setter.Value></span></div>
<div style="position:absolute;left:97.96px;top:480.00px" class="cls_007"><span class="cls_007"><ControlTemplate TargetType="{x:Type CustomControls:Sphere}"></span></div>
<div style="position:absolute;left:112.96px;top:493.50px" class="cls_007"><span class="cls_007"><ControlTemplate.Resources></span></div>
<div style="position:absolute;left:127.95px;top:507.00px" class="cls_007"><span class="cls_007"><DropShadowEffect x:Key="Shadow" BlurRadius="10"</span></div>
<div style="position:absolute;left:142.94px;top:520.50px" class="cls_007"><span class="cls_007">Direction="270" ShadowDepth="7" Opacity="0.5" /></span></div>
<div style="position:absolute;left:127.95px;top:534.00px" class="cls_007"><span class="cls_007"><LinearGradientBrush x:Key="Reflection"</span></div>
<div style="position:absolute;left:142.94px;top:547.50px" class="cls_007"><span class="cls_007">StartPoint="0,0" EndPoint="0,1"></span></div>
<div style="position:absolute;left:142.94px;top:561.00px" class="cls_007"><span class="cls_007"><GradientStop Color="#90FFFFFF" Offset="0.009" /></span></div>
<div style="position:absolute;left:142.94px;top:574.50px" class="cls_007"><span class="cls_007"><GradientStop Color="#2DFFFFFF" Offset="0.506" /></span></div>
<div style="position:absolute;left:142.94px;top:588.00px" class="cls_007"><span class="cls_007"><GradientStop Offset="0.991" /></span></div>
<div style="position:absolute;left:127.95px;top:601.50px" class="cls_007"><span class="cls_007"></LinearGradientBrush></span></div>
<div style="position:absolute;left:112.96px;top:615.00px" class="cls_007"><span class="cls_007"></ControlTemplate.Resources></span></div>
<div style="position:absolute;left:112.96px;top:628.50px" class="cls_007"><span class="cls_007"><Grid Height="{Binding Value,</span></div>
<div style="position:absolute;left:127.95px;top:642.00px" class="cls_007"><span class="cls_007">RelativeSource={RelativeSource TemplatedParent}}"</span></div>
<div style="position:absolute;left:127.95px;top:655.50px" class="cls_007"><span class="cls_007">Width="{Binding Value,</span></div>
<div style="position:absolute;left:127.95px;top:669.00px" class="cls_007"><span class="cls_007">RelativeSource={RelativeSource TemplatedParent}}"></span></div>
<div style="position:absolute;left:127.95px;top:682.50px" class="cls_007"><span class="cls_007"><Grid.RowDefinitions></span></div>
<div style="position:absolute;left:142.94px;top:696.00px" class="cls_007"><span class="cls_007"><RowDefinition Height="5*" /></span></div>
<div style="position:absolute;left:142.94px;top:709.50px" class="cls_007"><span class="cls_007"><RowDefinition Height="2*" /></span></div>
<div style="position:absolute;left:127.95px;top:723.00px" class="cls_007"><span class="cls_007"></Grid.RowDefinitions></span></div>
<div style="position:absolute;left:127.95px;top:736.50px" class="cls_007"><span class="cls_007"><Grid.ColumnDefinitions></span></div>
<div style="position:absolute;left:142.94px;top:750.00px" class="cls_007"><span class="cls_007"><ColumnDefinition Width="*" /></span></div>
<div style="position:absolute;left:142.94px;top:763.50px" class="cls_007"><span class="cls_007"><ColumnDefinition Width="8*" /></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:236590px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background297.jpg" width=612 height=792></div>
<div style="position:absolute;left:142.94px;top:3.00px" class="cls_007"><span class="cls_007"><ColumnDefinition Width="*" /></span></div>
<div style="position:absolute;left:127.95px;top:16.50px" class="cls_007"><span class="cls_007"></Grid.ColumnDefinitions></span></div>
<div style="position:absolute;left:127.95px;top:30.00px" class="cls_007"><span class="cls_007"><Ellipse Name="PART_Background" Grid.RowSpan="2"</span></div>
<div style="position:absolute;left:142.94px;top:43.50px" class="cls_007"><span class="cls_007">Grid.ColumnSpan="3" Stroke="#FF1B0000"</span></div>
<div style="position:absolute;left:142.94px;top:57.00px" class="cls_007"><span class="cls_007">Effect="{StaticResource Shadow}" /></span></div>
<div style="position:absolute;left:127.95px;top:70.50px" class="cls_007"><span class="cls_007"><Ellipse Name="PART_Glow" Grid.RowSpan="2"</span></div>
<div style="position:absolute;left:142.94px;top:84.00px" class="cls_007"><span class="cls_007">Grid.ColumnSpan="3" /></span></div>
<div style="position:absolute;left:127.95px;top:97.50px" class="cls_007"><span class="cls_007"><Ellipse Grid.Column="1" Margin="0,2,0,0"</span></div>
<div style="position:absolute;left:142.94px;top:111.00px" class="cls_007"><span class="cls_007">Fill="{StaticResource Reflection}" /></span></div>
<div style="position:absolute;left:112.96px;top:124.50px" class="cls_007"><span class="cls_007"></Grid></span></div>
<div style="position:absolute;left:97.96px;top:138.00px" class="cls_007"><span class="cls_007"></ControlTemplate></span></div>
<div style="position:absolute;left:82.97px;top:151.50px" class="cls_007"><span class="cls_007"></Setter.Value></span></div>
<div style="position:absolute;left:67.97px;top:165.00px" class="cls_007"><span class="cls_007"></Setter></span></div>
<div style="position:absolute;left:52.98px;top:178.50px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:5.00px;top:211.50px" class="cls_004"><span class="cls_004">When looking at our control's default template, we can see some resources defined in the</span></div>
<div style="position:absolute;left:5.00px;top:229.50px" class="cls_007"><span class="cls_007">ControlTemplate.Resources</span><span class="cls_004"> section. We first declare a </span><span class="cls_007">DropShadowEffect</span><span class="cls_004"> element, similar</span></div>
<div style="position:absolute;left:5.00px;top:247.50px" class="cls_004"><span class="cls_004">to our previous uses of this class. Next, we define a vertical </span><span class="cls_007">LinearGradientBrush</span><span class="cls_004"> element,</span></div>
<div style="position:absolute;left:5.00px;top:265.50px" class="cls_004"><span class="cls_004">to use as a light reflection layer, in a similar way to our example in an earlier section of this</span></div>
<div style="position:absolute;left:5.00px;top:283.50px" class="cls_004"><span class="cls_004">chapter.</span></div>
<div style="position:absolute;left:5.00px;top:301.50px" class="cls_004"><span class="cls_004">Previously, we saw that the default value of the </span><span class="cls_007">GradientStop.Offset</span><span class="cls_004"> property is zero and</span></div>
<div style="position:absolute;left:5.00px;top:319.50px" class="cls_004"><span class="cls_004">so we can omit the setting of this property if that is the value that we need to use. In this</span></div>
<div style="position:absolute;left:5.00px;top:337.50px" class="cls_004"><span class="cls_004">brush resource, we see that the last </span><span class="cls_007">GradientStop</span><span class="cls_004"> element has no </span><span class="cls_007">Color</span><span class="cls_004"> value specified.</span></div>
<div style="position:absolute;left:5.00px;top:355.50px" class="cls_004"><span class="cls_004">This is because its default value of this property is </span><span class="cls_007">Transparent</span><span class="cls_004"> and that is the value that</span></div>
<div style="position:absolute;left:5.00px;top:373.50px" class="cls_004"><span class="cls_004">we need to use here.</span></div>
<div style="position:absolute;left:5.00px;top:391.50px" class="cls_004"><span class="cls_004">In the actual markup for our control, we declare three </span><span class="cls_007">Ellipse</span><span class="cls_004"> objects within a </span><span class="cls_007">Grid</span><span class="cls_004"> panel.</span></div>
<div style="position:absolute;left:5.00px;top:409.50px" class="cls_004"><span class="cls_004">Two of these elements are named and referenced in the control's code, while the third</span></div>
<div style="position:absolute;left:5.00px;top:427.50px" class="cls_004"><span class="cls_004">ellipse uses the brush from resources to create the 'shine' on top of the other ellipses. The</span></div>
<div style="position:absolute;left:5.00px;top:445.50px" class="cls_004"><span class="cls_004">panel's size properties are data bound to the </span><span class="cls_007">Value</span><span class="cls_004"> Dependency Property, using a</span></div>
<div style="position:absolute;left:5.00px;top:463.50px" class="cls_007"><span class="cls_007">TemplatedParent</span><span class="cls_004"> source.</span></div>
<div style="position:absolute;left:5.00px;top:481.50px" class="cls_004"><span class="cls_004">Note that we have used the star-sizing capabilities of the </span><span class="cls_007">Grid</span><span class="cls_004"> panel to both position and</span></div>
<div style="position:absolute;left:5.00px;top:499.50px" class="cls_004"><span class="cls_004">size our ellipse elements, with the exception of the two pixels of top margin specified on the</span></div>
<div style="position:absolute;left:5.00px;top:517.50px" class="cls_004"><span class="cls_004">reflection ellipse. In this way, our control can be any size and the positioning of the various</span></div>
<div style="position:absolute;left:5.00px;top:535.50px" class="cls_004"><span class="cls_004">layers will remain visually correct. Note that we could not achieve this by hardcoding exact</span></div>
<div style="position:absolute;left:5.00px;top:553.50px" class="cls_004"><span class="cls_004">margin values for each element.</span></div>
<div style="position:absolute;left:5.00px;top:571.50px" class="cls_004"><span class="cls_004">Let's see how we could use this in a simple view:</span></div>
<div style="position:absolute;left:52.98px;top:594.75px" class="cls_007"><span class="cls_007"><Grid TextElement.FontSize="28" TextElement.FontWeight="Bold"</span></div>
<div style="position:absolute;left:52.98px;top:608.25px" class="cls_007"><span class="cls_007">Margin="20"></span></div>
<div style="position:absolute;left:67.97px;top:621.75px" class="cls_007"><span class="cls_007"><Grid.ColumnDefinitions></span></div>
<div style="position:absolute;left:82.97px;top:635.25px" class="cls_007"><span class="cls_007"><ColumnDefinition /></span></div>
<div style="position:absolute;left:82.97px;top:648.75px" class="cls_007"><span class="cls_007"><ColumnDefinition /></span></div>
<div style="position:absolute;left:67.97px;top:662.25px" class="cls_007"><span class="cls_007"></Grid.ColumnDefinitions></span></div>
<div style="position:absolute;left:67.97px;top:675.75px" class="cls_007"><span class="cls_007"><Grid.RowDefinitions></span></div>
<div style="position:absolute;left:82.97px;top:689.25px" class="cls_007"><span class="cls_007"><RowDefinition /></span></div>
<div style="position:absolute;left:82.97px;top:702.75px" class="cls_007"><span class="cls_007"><RowDefinition Height="Auto" /></span></div>
<div style="position:absolute;left:67.97px;top:716.25px" class="cls_007"><span class="cls_007"></Grid.RowDefinitions></span></div>
<div style="position:absolute;left:67.97px;top:729.75px" class="cls_007"><span class="cls_007"><CustomControls:Sphere Color="Red" Value="{Binding InCount}"</span></div>
<div style="position:absolute;left:82.97px;top:743.25px" class="cls_007"><span class="cls_007">VerticalAlignment="Bottom" /></span></div>
<div style="position:absolute;left:67.97px;top:756.75px" class="cls_007"><span class="cls_007"><CustomControls:Sphere Grid.Column="1" Value="{Binding OutCount}"</span></div>
<div style="position:absolute;left:82.97px;top:770.25px" class="cls_007"><span class="cls_007">VerticalAlignment="Bottom" /></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:237392px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background298.jpg" width=612 height=792></div>
<div style="position:absolute;left:67.97px;top:3.00px" class="cls_007"><span class="cls_007"><TextBlock Grid.Row="1" Text="{Binding InCount}"</span></div>
<div style="position:absolute;left:82.97px;top:16.50px" class="cls_007"><span class="cls_007">HorizontalAlignment="Center" Margin="0,10,0,0" /></span></div>
<div style="position:absolute;left:67.97px;top:30.00px" class="cls_007"><span class="cls_007"><TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding OutCount}"</span></div>
<div style="position:absolute;left:82.97px;top:43.50px" class="cls_007"><span class="cls_007">HorizontalAlignment="Center" Margin="0,10,0,0" /></span></div>
<div style="position:absolute;left:52.98px;top:57.00px" class="cls_007"><span class="cls_007"></Grid></span></div>
<div style="position:absolute;left:5.00px;top:90.00px" class="cls_004"><span class="cls_004">This is how our example looks when rendered.</span></div>
<div style="position:absolute;left:5.00px;top:368.25px" class="cls_004"><span class="cls_004">As you can see, WPF is very powerful and enables us to create completely original looking</span></div>
<div style="position:absolute;left:5.00px;top:386.25px" class="cls_004"><span class="cls_004">controls. However, we can also use it to recreate more commonly seen controls. As an</span></div>
<div style="position:absolute;left:5.00px;top:404.25px" class="cls_004"><span class="cls_004">example, let's see how we can create an alternative control to gauge how close we may be</span></div>
<div style="position:absolute;left:5.00px;top:422.25px" class="cls_004"><span class="cls_004">to our particular target value.</span></div>
<div style="position:absolute;left:5.00px;top:711.75px" class="cls_004"><span class="cls_004">This example features a semi-circular arc, which is something that does not exist in a form</span></div>
<div style="position:absolute;left:5.00px;top:729.75px" class="cls_004"><span class="cls_004">that is usable from XAML, so we'll first create an </span><span class="cls_007">Arc</span><span class="cls_004"> control to use internally within our</span></div>
<div style="position:absolute;left:5.00px;top:747.75px" class="cls_007"><span class="cls_007">Gauge</span><span class="cls_004"> control. Let's see how we can achieve this, by adding a new custom control:</span></div>
<div style="position:absolute;left:52.98px;top:771.00px" class="cls_007"><span class="cls_007">using System;</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:238194px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background299.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:3.00px" class="cls_007"><span class="cls_007">using System.Windows;</span></div>
<div style="position:absolute;left:52.98px;top:16.50px" class="cls_007"><span class="cls_007">using System.Windows.Media;</span></div>
<div style="position:absolute;left:52.98px;top:30.00px" class="cls_007"><span class="cls_007">using System.Windows.Shapes;</span></div>
<div style="position:absolute;left:52.98px;top:57.00px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.CustomControls</span></div>
<div style="position:absolute;left:52.98px;top:70.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:84.00px" class="cls_007"><span class="cls_007">public class Arc : Shape</span></div>
<div style="position:absolute;left:67.97px;top:97.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:111.00px" class="cls_007"><span class="cls_007">public static readonly DependencyProperty StartAngleProperty =</span></div>
<div style="position:absolute;left:97.96px;top:124.50px" class="cls_007"><span class="cls_007">DependencyProperty.Register(nameof(StartAngle),</span></div>
<div style="position:absolute;left:52.98px;top:138.00px" class="cls_007"><span class="cls_007">typeof(double),</span></div>
<div style="position:absolute;left:97.96px;top:151.50px" class="cls_007"><span class="cls_007">typeof(Arc), new PropertyMetadata(180.0));</span></div>
<div style="position:absolute;left:82.97px;top:178.50px" class="cls_007"><span class="cls_007">public double StartAngle</span></div>
<div style="position:absolute;left:82.97px;top:192.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:205.50px" class="cls_007"><span class="cls_007">get { return (double)GetValue(StartAngleProperty); }</span></div>
<div style="position:absolute;left:97.96px;top:219.00px" class="cls_007"><span class="cls_007">set { SetValue(StartAngleProperty, value); }</span></div>
<div style="position:absolute;left:82.97px;top:232.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:259.50px" class="cls_007"><span class="cls_007">public static readonly DependencyProperty EndAngleProperty =</span></div>
<div style="position:absolute;left:97.96px;top:273.00px" class="cls_007"><span class="cls_007">DependencyProperty.Register(nameof(EndAngle), typeof(double),</span></div>
<div style="position:absolute;left:97.96px;top:286.50px" class="cls_007"><span class="cls_007">typeof(Arc), new PropertyMetadata(0.0));</span></div>
<div style="position:absolute;left:82.97px;top:313.50px" class="cls_007"><span class="cls_007">public double EndAngle</span></div>
<div style="position:absolute;left:82.97px;top:327.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:340.50px" class="cls_007"><span class="cls_007">get { return (double)GetValue(EndAngleProperty); }</span></div>
<div style="position:absolute;left:97.96px;top:354.00px" class="cls_007"><span class="cls_007">set { SetValue(EndAngleProperty, value); }</span></div>
<div style="position:absolute;left:82.97px;top:367.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:394.50px" class="cls_007"><span class="cls_007">protected override Geometry DefiningGeometry</span></div>
<div style="position:absolute;left:82.97px;top:408.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:421.50px" class="cls_007"><span class="cls_007">get { return GetArcGeometry(); }</span></div>
<div style="position:absolute;left:82.97px;top:435.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:462.00px" class="cls_007"><span class="cls_007">private Geometry GetArcGeometry()</span></div>
<div style="position:absolute;left:82.97px;top:475.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:489.00px" class="cls_007"><span class="cls_007">Point startPoint = ConvertToPoint(Math.Min(StartAngle,</span></div>
<div style="position:absolute;left:52.98px;top:502.50px" class="cls_007"><span class="cls_007">EndAngle));</span></div>
<div style="position:absolute;left:97.96px;top:516.00px" class="cls_007"><span class="cls_007">Point endPoint = ConvertToPoint(Math.Max(StartAngle,</span></div>
<div style="position:absolute;left:52.98px;top:529.50px" class="cls_007"><span class="cls_007">EndAngle));</span></div>
<div style="position:absolute;left:97.96px;top:543.00px" class="cls_007"><span class="cls_007">Size arcSize = new Size(Math.Max(0, (RenderSize.Width -</span></div>
<div style="position:absolute;left:112.96px;top:556.50px" class="cls_007"><span class="cls_007">StrokeThickness) / 2), Math.Max(0, (RenderSize.Height -</span></div>
<div style="position:absolute;left:112.96px;top:570.00px" class="cls_007"><span class="cls_007">StrokeThickness) / 2));</span></div>
<div style="position:absolute;left:97.96px;top:583.50px" class="cls_007"><span class="cls_007">bool isLargeArc = Math.Abs(EndAngle - StartAngle) > 180;</span></div>
<div style="position:absolute;left:97.96px;top:597.00px" class="cls_007"><span class="cls_007">StreamGeometry streamGeometry = new StreamGeometry();</span></div>
<div style="position:absolute;left:97.96px;top:610.50px" class="cls_007"><span class="cls_007">using (StreamGeometryContext context = streamGeometry.Open())</span></div>
<div style="position:absolute;left:97.96px;top:624.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:112.96px;top:637.50px" class="cls_007"><span class="cls_007">context.BeginFigure(startPoint, false, false);</span></div>
<div style="position:absolute;left:112.96px;top:651.00px" class="cls_007"><span class="cls_007">context.ArcTo(endPoint, arcSize, 0, isLargeArc,</span></div>
<div style="position:absolute;left:127.95px;top:664.50px" class="cls_007"><span class="cls_007">SweepDirection.Counterclockwise, true, false);</span></div>
<div style="position:absolute;left:97.96px;top:678.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:97.96px;top:691.50px" class="cls_007"><span class="cls_007">streamGeometry.Transform =</span></div>
<div style="position:absolute;left:112.96px;top:705.00px" class="cls_007"><span class="cls_007">new TranslateTransform(StrokeThickness / 2, StrokeThickness</span></div>
<div style="position:absolute;left:52.98px;top:718.50px" class="cls_007"><span class="cls_007">/ 2);</span></div>
<div style="position:absolute;left:97.96px;top:732.00px" class="cls_007"><span class="cls_007">streamGeometry.Freeze();</span></div>
<div style="position:absolute;left:97.96px;top:745.50px" class="cls_007"><span class="cls_007">return streamGeometry;</span></div>
<div style="position:absolute;left:82.97px;top:759.00px" class="cls_007"><span class="cls_007">}</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:238996px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background300.jpg" width=612 height=792></div>
<div style="position:absolute;left:82.97px;top:3.00px" class="cls_007"><span class="cls_007">private Point ConvertToPoint(double angleInDegrees)</span></div>
<div style="position:absolute;left:82.97px;top:16.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:30.00px" class="cls_007"><span class="cls_007">double angleInRadians = angleInDegrees * Math.PI / 180;</span></div>
<div style="position:absolute;left:97.96px;top:43.50px" class="cls_007"><span class="cls_007">double radiusX = (RenderSize.Width - StrokeThickness) / 2;</span></div>
<div style="position:absolute;left:97.96px;top:57.00px" class="cls_007"><span class="cls_007">double radiusY = (RenderSize.Height - StrokeThickness) / 2;</span></div>
<div style="position:absolute;left:97.96px;top:70.50px" class="cls_007"><span class="cls_007">return new Point(radiusX * Math.Cos(angleInRadians) +</span></div>
<div style="position:absolute;left:52.98px;top:84.00px" class="cls_007"><span class="cls_007">radiusX,</span></div>
<div style="position:absolute;left:112.96px;top:97.50px" class="cls_007"><span class="cls_007">radiusY * Math.Sin(-angleInRadians) + radiusY);</span></div>
<div style="position:absolute;left:82.97px;top:111.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:124.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:138.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:171.00px" class="cls_004"><span class="cls_004">Note that we extend the </span><span class="cls_007">Shape</span><span class="cls_004"> class when creating our </span><span class="cls_007">Arc</span><span class="cls_004"> class. We do this because it</span></div>
<div style="position:absolute;left:5.00px;top:189.00px" class="cls_004"><span class="cls_004">provides us with a wide variety of stroke and fill properties and also the apparatus to render</span></div>
<div style="position:absolute;left:5.00px;top:207.00px" class="cls_004"><span class="cls_004">our custom shape from a </span><span class="cls_007">Geometry</span><span class="cls_004"> object. Additionally, users of our </span><span class="cls_007">Arc</span><span class="cls_004"> control will also be</span></div>
<div style="position:absolute;left:5.00px;top:225.00px" class="cls_004"><span class="cls_004">able to take advantage of the </span><span class="cls_007">Shape</span><span class="cls_004"> class' transformation abilities through its </span><span class="cls_007">Stretch</span><span class="cls_004"> and</span></div>
<div style="position:absolute;left:5.00px;top:243.00px" class="cls_007"><span class="cls_007">GeometryTransform</span><span class="cls_004"> properties.</span></div>
<div style="position:absolute;left:5.00px;top:261.00px" class="cls_004"><span class="cls_004">To draw our arc, we will use the </span><span class="cls_007">ArcTo</span><span class="cls_004"> method of the </span><span class="cls_007">StreamGeometryContext</span><span class="cls_004"> class and</span></div>
<div style="position:absolute;left:5.00px;top:279.00px" class="cls_004"><span class="cls_004">with it, we need to specify exact </span><span class="cls_007">Point</span><span class="cls_004"> values for its start and end. However, in order to</span></div>
<div style="position:absolute;left:5.00px;top:297.00px" class="cls_004"><span class="cls_004">reflect the correct value in the size of our arc, it is easier to define it using angle values for</span></div>
<div style="position:absolute;left:5.00px;top:315.00px" class="cls_004"><span class="cls_004">its start and end. Therefore, we add </span><span class="cls_007">StartAngle</span><span class="cls_004"> and </span><span class="cls_007">EndAngle</span><span class="cls_004"> Dependency Properties to</span></div>
<div style="position:absolute;left:5.00px;top:333.00px" class="cls_004"><span class="cls_004">our </span><span class="cls_007">Arc</span><span class="cls_004"> class.</span></div>
<div style="position:absolute;left:5.00px;top:351.00px" class="cls_004"><span class="cls_004">After these property declarations, we see the overridden </span><span class="cls_007">DefiningGeometry</span><span class="cls_004"> property, that</span></div>
<div style="position:absolute;left:5.00px;top:369.00px" class="cls_004"><span class="cls_004">enables us to return a </span><span class="cls_007">Geometry</span><span class="cls_004"> object that defines the shape to be rendered. We simply</span></div>
<div style="position:absolute;left:5.00px;top:387.00px" class="cls_004"><span class="cls_004">return the result from the </span><span class="cls_007">GetArcGeometry</span><span class="cls_004"> method from this property.</span></div>
<div style="position:absolute;left:5.00px;top:405.00px" class="cls_004"><span class="cls_004">In the </span><span class="cls_007">GetArcGeometry</span><span class="cls_004"> method, we obtain the required start and end </span><span class="cls_007">Point</span><span class="cls_004"> elements from</span></div>
<div style="position:absolute;left:5.00px;top:423.00px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">ConvertToPoint</span><span class="cls_004"> method, passing in the </span><span class="cls_007">StartAngle</span><span class="cls_004"> and </span><span class="cls_007">EndAngle</span><span class="cls_004"> property values. Note</span></div>
<div style="position:absolute;left:5.00px;top:441.00px" class="cls_004"><span class="cls_004">that we use the </span><span class="cls_007">Min</span><span class="cls_004"> and </span><span class="cls_007">Max</span><span class="cls_004"> methods of the </span><span class="cls_007">Math</span><span class="cls_004"> class here to ensure that the start point is</span></div>
<div style="position:absolute;left:5.00px;top:459.00px" class="cls_004"><span class="cls_004">calculated from the smaller angle and the end point is calculated from the larger angle.</span></div>
<div style="position:absolute;left:5.00px;top:477.00px" class="cls_004"><span class="cls_004">Our arc shape's fill will actually come from the geometric arc's stroke and so we will not be</span></div>
<div style="position:absolute;left:5.00px;top:495.00px" class="cls_004"><span class="cls_004">able to add a stroke to it. In WPF, the stroke of a shape with a thickness of one pixel will</span></div>
<div style="position:absolute;left:5.00px;top:513.00px" class="cls_004"><span class="cls_004">extend no further than the shape's bounding box. However, at the furthest point, strokes</span></div>
<div style="position:absolute;left:5.00px;top:531.00px" class="cls_004"><span class="cls_004">with larger thickness values are rendered so that their center remains on the line of the</span></div>
<div style="position:absolute;left:5.00px;top:549.00px" class="cls_004"><span class="cls_004">bounding box and therefore, half of it will extend outside the bounds of the element and half</span></div>
<div style="position:absolute;left:5.00px;top:567.00px" class="cls_004"><span class="cls_004">will be rendered within the bounds.</span></div>
<div style="position:absolute;left:5.00px;top:749.25px" class="cls_004"><span class="cls_004">Therefore, we calculate the size of the arc by dividing the </span><span class="cls_007">RenderSize</span><span class="cls_004"> value minus the</span></div>
<div style="position:absolute;left:5.00px;top:767.25px" class="cls_007"><span class="cls_007">StrokeThickness</span><span class="cls_004"> value by two. This will reduce the size of the arc so that it remains totally</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:239798px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background301.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">within the bounds of our control. We make use of the </span><span class="cls_007">Math.Max</span><span class="cls_004"> method to ensure that the</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">values that we pass to the </span><span class="cls_007">Size</span><span class="cls_004"> class are never less than zero and avoid exceptions.</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">When using the </span><span class="cls_007">ArcTo</span><span class="cls_004"> method, we need to specify a value that determines whether we</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">want to connect our start and end points with a short arc or a long one. Our </span><span class="cls_007">isLargeArc</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">variable therefore determines whether the two specified angles would produce an arc of</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">more than one hundred and eighty degrees or not.</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">Next, we create a </span><span class="cls_007">StreamGeometry</span><span class="cls_004"> object and retrieve a </span><span class="cls_007">StreamGeometryContext</span><span class="cls_004"> object</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">from its </span><span class="cls_007">Open</span><span class="cls_004"> method, with which to define our geometric shape. Note that we could equally</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">use a </span><span class="cls_007">PathGeometry</span><span class="cls_004"> object here, but as we do not need its data binding, animation, or other</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">abilities, we use the more efficient </span><span class="cls_007">StreamGeometry</span><span class="cls_004"> object instead.</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">We enter the arc's start point in the </span><span class="cls_007">BeginFigure</span><span class="cls_004"> method and the remaining parameters in</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">ArcTo</span><span class="cls_004"> method. Note that we call these methods on our </span><span class="cls_007">StreamGeometryContext</span><span class="cls_004"> object</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">from within a </span><span class="cls_007">using</span><span class="cls_004"> statement to ensure that it is closed and disposed of properly, once we</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">are finished with it.</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">Next, we apply a </span><span class="cls_007">TranslateTransform</span><span class="cls_004"> element to the </span><span class="cls_007">Transform</span><span class="cls_004"> property of the</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_007"><span class="cls_007">StreamGeometry</span><span class="cls_004"> object in order to shift the arc so that it is fully contained within our control.</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">Without this step, our arc would stick out of the bounding box of our control to the upper</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">left, by the amount of half of the </span><span class="cls_007">StrokeThickness</span><span class="cls_004"> property value.</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_004"><span class="cls_004">Once we have finished manipulating our </span><span class="cls_007">StreamGeometry</span><span class="cls_004"> object, we call its </span><span class="cls_007">Freeze</span><span class="cls_004"> method,</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_004"><span class="cls_004">which makes it unmodifiable and rewards us with additional performance benefits. We'll find</span></div>
<div style="position:absolute;left:5.00px;top:363.75px" class="cls_004"><span class="cls_004">out more about this in </span><span class="cls_015">Chapter 10</span><span class="cls_004">, </span><span class="cls_006">Improving Application Performance</span><span class="cls_004">, but for now, let's</span></div>
<div style="position:absolute;left:5.00px;top:382.50px" class="cls_004"><span class="cls_004">continue looking through this example.</span></div>
<div style="position:absolute;left:5.00px;top:400.50px" class="cls_004"><span class="cls_004">Finally, we get to the </span><span class="cls_007">ConvertToPoint</span><span class="cls_004"> method, which converts the values of our two angle</span></div>
<div style="position:absolute;left:5.00px;top:418.50px" class="cls_004"><span class="cls_004">Dependency Properties to two-dimensional </span><span class="cls_007">Point</span><span class="cls_004"> objects. Our first job is to convert each</span></div>
<div style="position:absolute;left:5.00px;top:436.50px" class="cls_004"><span class="cls_004">angle from degrees to radians, as the methods of the </span><span class="cls_007">Math</span><span class="cls_004"> class that we need to use</span></div>
<div style="position:absolute;left:5.00px;top:454.50px" class="cls_004"><span class="cls_004">require radian values.</span></div>
<div style="position:absolute;left:5.00px;top:472.50px" class="cls_004"><span class="cls_004">Next, we calculate the two radii of our arc, using half of the </span><span class="cls_007">RenderSize</span><span class="cls_004"> value minus the</span></div>
<div style="position:absolute;left:5.00px;top:490.50px" class="cls_007"><span class="cls_007">StrokeThickness</span><span class="cls_004"> property value, so that the size of the arc does not exceed the bounding</span></div>
<div style="position:absolute;left:5.00px;top:508.50px" class="cls_004"><span class="cls_004">box of our </span><span class="cls_007">Arc</span><span class="cls_004"> control. Finally, we perform some basic trigonometry using the </span><span class="cls_007">Math.Cos</span><span class="cls_004"> and</span></div>
<div style="position:absolute;left:5.00px;top:526.50px" class="cls_007"><span class="cls_007">Math.Sin</span><span class="cls_004"> methods when calculating the </span><span class="cls_007">Point</span><span class="cls_004"> element to return.</span></div>
<div style="position:absolute;left:5.00px;top:544.50px" class="cls_004"><span class="cls_004">That completes our simple </span><span class="cls_007">Arc</span><span class="cls_004"> control and so now we can utilize this new class in our </span><span class="cls_007">Gauge</span></div>
<div style="position:absolute;left:5.00px;top:562.50px" class="cls_004"><span class="cls_004">control. We'll need to create another new custom control for it, so let's first see the</span></div>
<div style="position:absolute;left:5.00px;top:580.50px" class="cls_004"><span class="cls_004">properties and code in our new </span><span class="cls_007">Gauge</span><span class="cls_004"> class:</span></div>
<div style="position:absolute;left:52.98px;top:603.75px" class="cls_007"><span class="cls_007">using System.Windows;</span></div>
<div style="position:absolute;left:52.98px;top:617.25px" class="cls_007"><span class="cls_007">using System.Windows.Controls;</span></div>
<div style="position:absolute;left:52.98px;top:644.25px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.CustomControls</span></div>
<div style="position:absolute;left:52.98px;top:657.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:671.25px" class="cls_007"><span class="cls_007">public class Gauge : Control</span></div>
<div style="position:absolute;left:67.97px;top:684.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:698.25px" class="cls_007"><span class="cls_007">static Gauge()</span></div>
<div style="position:absolute;left:82.97px;top:711.75px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:725.25px" class="cls_007"><span class="cls_007">DefaultStyleKeyProperty.OverrideMetadata (typeof(Gauge),</span></div>
<div style="position:absolute;left:112.96px;top:738.75px" class="cls_007"><span class="cls_007">new FrameworkPropertyMetadata(typeof(Gauge)));</span></div>
<div style="position:absolute;left:82.97px;top:752.25px" class="cls_007"><span class="cls_007">}</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:240600px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background302.jpg" width=612 height=792></div>
<div style="position:absolute;left:82.97px;top:3.00px" class="cls_007"><span class="cls_007">public static readonly DependencyPropertyKey</span></div>
<div style="position:absolute;left:52.98px;top:16.50px" class="cls_007"><span class="cls_007">valueAnglePropertyKey =</span></div>
<div style="position:absolute;left:97.96px;top:30.00px" class="cls_007"><span class="cls_007">DependencyProperty.RegisterReadOnly(nameof(ValueAngle),</span></div>
<div style="position:absolute;left:97.96px;top:43.50px" class="cls_007"><span class="cls_007">typeof(double), typeof(Gauge), new PropertyMetadata(180.0));</span></div>
<div style="position:absolute;left:82.97px;top:70.50px" class="cls_007"><span class="cls_007">public static readonly DependencyProperty ValueAngleProperty =</span></div>
<div style="position:absolute;left:97.96px;top:84.00px" class="cls_007"><span class="cls_007">valueAnglePropertyKey.DependencyProperty;</span></div>
<div style="position:absolute;left:82.97px;top:111.00px" class="cls_007"><span class="cls_007">public double ValueAngle</span></div>
<div style="position:absolute;left:82.97px;top:124.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:138.00px" class="cls_007"><span class="cls_007">get { return (double)GetValue(ValueAngleProperty); }</span></div>
<div style="position:absolute;left:97.96px;top:151.50px" class="cls_007"><span class="cls_007">private set { SetValue(valueAnglePropertyKey, value); }</span></div>
<div style="position:absolute;left:82.97px;top:165.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:192.00px" class="cls_007"><span class="cls_007">public static readonly DependencyPropertyKey</span></div>
<div style="position:absolute;left:97.96px;top:205.50px" class="cls_007"><span class="cls_007">rotationAnglePropertyKey =</span></div>
<div style="position:absolute;left:52.98px;top:219.00px" class="cls_007"><span class="cls_007">DependencyProperty.RegisterReadOnly(</span></div>
<div style="position:absolute;left:97.96px;top:232.50px" class="cls_007"><span class="cls_007">nameof(RotationAngle), typeof(double), typeof(Gauge),</span></div>
<div style="position:absolute;left:97.96px;top:246.00px" class="cls_007"><span class="cls_007">new PropertyMetadata(180.0));</span></div>
<div style="position:absolute;left:82.97px;top:273.00px" class="cls_007"><span class="cls_007">public static readonly DependencyProperty RotationAngleProperty</span></div>
<div style="position:absolute;left:52.98px;top:286.50px" class="cls_007"><span class="cls_007">=</span></div>
<div style="position:absolute;left:97.96px;top:300.00px" class="cls_007"><span class="cls_007">rotationAnglePropertyKey.DependencyProperty;</span></div>
<div style="position:absolute;left:82.97px;top:327.00px" class="cls_007"><span class="cls_007">public double RotationAngle</span></div>
<div style="position:absolute;left:82.97px;top:340.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:354.00px" class="cls_007"><span class="cls_007">get { return (double)GetValue(RotationAngleProperty); }</span></div>
<div style="position:absolute;left:97.96px;top:367.50px" class="cls_007"><span class="cls_007">private set { SetValue(rotationAnglePropertyKey, value); }</span></div>
<div style="position:absolute;left:82.97px;top:381.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:408.00px" class="cls_007"><span class="cls_007">public static readonly DependencyProperty ValueProperty =</span></div>
<div style="position:absolute;left:97.96px;top:421.50px" class="cls_007"><span class="cls_007">DependencyProperty.Register(nameof(Value), typeof(double),</span></div>
<div style="position:absolute;left:97.96px;top:435.00px" class="cls_007"><span class="cls_007">typeof(Gauge), new PropertyMetadata(0.0, OnValueChanged));</span></div>
<div style="position:absolute;left:82.97px;top:462.00px" class="cls_007"><span class="cls_007">private static void OnValueChanged(DependencyObject</span></div>
<div style="position:absolute;left:97.96px;top:475.50px" class="cls_007"><span class="cls_007">dependencyObject, DependencyPropertyChangedEventArgs e)</span></div>
<div style="position:absolute;left:82.97px;top:489.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:502.50px" class="cls_007"><span class="cls_007">Gauge gauge = (Gauge)dependencyObject;</span></div>
<div style="position:absolute;left:97.96px;top:516.00px" class="cls_007"><span class="cls_007">if (gauge.MaximumValue == 0.0)</span></div>
<div style="position:absolute;left:112.96px;top:529.50px" class="cls_007"><span class="cls_007">gauge.ValueAngle = gauge.RotationAngle = 180.0;</span></div>
<div style="position:absolute;left:97.96px;top:543.00px" class="cls_007"><span class="cls_007">else if ((double)e.NewValue > gauge.MaximumValue)</span></div>
<div style="position:absolute;left:97.96px;top:556.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:112.96px;top:570.00px" class="cls_007"><span class="cls_007">gauge.ValueAngle = 0.0;</span></div>
<div style="position:absolute;left:112.96px;top:583.50px" class="cls_007"><span class="cls_007">gauge.RotationAngle = 360.0;</span></div>
<div style="position:absolute;left:97.96px;top:597.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:97.96px;top:610.50px" class="cls_007"><span class="cls_007">else</span></div>
<div style="position:absolute;left:97.96px;top:624.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:112.96px;top:637.50px" class="cls_007"><span class="cls_007">double scaledPercentageValue =</span></div>
<div style="position:absolute;left:127.95px;top:651.00px" class="cls_007"><span class="cls_007">((double)e.NewValue / gauge.MaximumValue) * 180.0;</span></div>
<div style="position:absolute;left:112.96px;top:664.50px" class="cls_007"><span class="cls_007">gauge.ValueAngle = 180.0 - scaledPercentageValue;</span></div>
<div style="position:absolute;left:112.96px;top:678.00px" class="cls_007"><span class="cls_007">gauge.RotationAngle = 180.0 + scaledPercentageValue;</span></div>
<div style="position:absolute;left:97.96px;top:691.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:705.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:732.00px" class="cls_007"><span class="cls_007">public double Value</span></div>
<div style="position:absolute;left:82.97px;top:745.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:759.00px" class="cls_007"><span class="cls_007">get { return (double)GetValue(ValueProperty); }</span></div>
<div style="position:absolute;left:97.96px;top:772.50px" class="cls_007"><span class="cls_007">set { SetValue(ValueProperty, value); }</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:241402px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background303.jpg" width=612 height=792></div>
<div style="position:absolute;left:82.97px;top:3.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:30.00px" class="cls_007"><span class="cls_007">public static readonly DependencyProperty MaximumValueProperty</span></div>
<div style="position:absolute;left:52.98px;top:43.50px" class="cls_007"><span class="cls_007">=</span></div>
<div style="position:absolute;left:97.96px;top:57.00px" class="cls_007"><span class="cls_007">DependencyProperty.Register(nameof(MaximumValue),</span></div>
<div style="position:absolute;left:52.98px;top:70.50px" class="cls_007"><span class="cls_007">typeof(double),</span></div>
<div style="position:absolute;left:97.96px;top:84.00px" class="cls_007"><span class="cls_007">typeof(Gauge), new PropertyMetadata(0.0));</span></div>
<div style="position:absolute;left:82.97px;top:111.00px" class="cls_007"><span class="cls_007">public double MaximumValue</span></div>
<div style="position:absolute;left:82.97px;top:124.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:138.00px" class="cls_007"><span class="cls_007">get { return (double)GetValue(MaximumValueProperty); }</span></div>
<div style="position:absolute;left:97.96px;top:151.50px" class="cls_007"><span class="cls_007">set { SetValue(MaximumValueProperty, value); }</span></div>
<div style="position:absolute;left:82.97px;top:165.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:192.00px" class="cls_007"><span class="cls_007">public static readonly DependencyProperty TitleProperty =</span></div>
<div style="position:absolute;left:97.96px;top:205.50px" class="cls_007"><span class="cls_007">DependencyProperty.Register(nameof(Title), typeof(string),</span></div>
<div style="position:absolute;left:97.96px;top:219.00px" class="cls_007"><span class="cls_007">typeof(Gauge), new PropertyMetadata(string.Empty));</span></div>
<div style="position:absolute;left:82.97px;top:246.00px" class="cls_007"><span class="cls_007">public string Title</span></div>
<div style="position:absolute;left:82.97px;top:259.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:273.00px" class="cls_007"><span class="cls_007">get { return (string)GetValue(TitleProperty); }</span></div>
<div style="position:absolute;left:97.96px;top:286.50px" class="cls_007"><span class="cls_007">set { SetValue(TitleProperty, value); }</span></div>
<div style="position:absolute;left:82.97px;top:300.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:313.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:327.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:360.00px" class="cls_004"><span class="cls_004">As usual, we start by overriding the metadata of the </span><span class="cls_007">DefaultStyleKeyProperty</span><span class="cls_004"> for our</span></div>
<div style="position:absolute;left:5.00px;top:378.00px" class="cls_004"><span class="cls_004">control type in the static constructor, to help the Framework find where its default style is</span></div>
<div style="position:absolute;left:5.00px;top:396.00px" class="cls_004"><span class="cls_004">defined. We then declare the internal, read-only </span><span class="cls_007">ValueAngle</span><span class="cls_004"> and </span><span class="cls_007">RotationAngle</span></div>
<div style="position:absolute;left:5.00px;top:414.00px" class="cls_004"><span class="cls_004">Dependency Properties and the regular public </span><span class="cls_007">Value</span><span class="cls_004">, </span><span class="cls_007">MaximumValue</span><span class="cls_004"> and </span><span class="cls_007">Title</span><span class="cls_004"> Dependency</span></div>
<div style="position:absolute;left:5.00px;top:432.00px" class="cls_004"><span class="cls_004">Properties.</span></div>
<div style="position:absolute;left:5.00px;top:450.00px" class="cls_004"><span class="cls_004">We declare a </span><span class="cls_007">PropertyChangedCallback</span><span class="cls_004"> hander for the </span><span class="cls_007">Value</span><span class="cls_004"> property and in that method,</span></div>
<div style="position:absolute;left:5.00px;top:468.00px" class="cls_004"><span class="cls_004">we first cast the </span><span class="cls_007">dependencyObject</span><span class="cls_004"> input parameter to an instance of our </span><span class="cls_007">Gauge</span><span class="cls_004"> class. If the</span></div>
<div style="position:absolute;left:5.00px;top:486.00px" class="cls_004"><span class="cls_004">value of the </span><span class="cls_007">MaximumValue</span><span class="cls_004"> property is zero, then we simply set both of the </span><span class="cls_007">ValueAngle</span><span class="cls_004"> and</span></div>
<div style="position:absolute;left:5.00px;top:504.00px" class="cls_007"><span class="cls_007">RotationAngle</span><span class="cls_004"> properties to </span><span class="cls_007">180</span><span class="cls_004"> </span><span class="cls_007">.0</span><span class="cls_004">, which results in the arc and needle displaying in their</span></div>
<div style="position:absolute;left:5.00px;top:522.00px" class="cls_004"><span class="cls_004">start positions, to the left.</span></div>
<div style="position:absolute;left:5.00px;top:540.00px" class="cls_004"><span class="cls_004">If the new value of the data bound </span><span class="cls_007">Value</span><span class="cls_004"> property is more than the value of the</span></div>
<div style="position:absolute;left:5.00px;top:558.00px" class="cls_007"><span class="cls_007">MaximumValue</span><span class="cls_004"> property, then we make the arc and needle display in their end, or full,</span></div>
<div style="position:absolute;left:5.00px;top:576.00px" class="cls_004"><span class="cls_004">positions to the right. We do this by setting the </span><span class="cls_007">ValueAngle</span><span class="cls_004"> property to </span><span class="cls_007">0.0</span><span class="cls_004"> and the</span></div>
<div style="position:absolute;left:5.00px;top:594.00px" class="cls_007"><span class="cls_007">RotationAngle</span><span class="cls_004"> property to </span><span class="cls_007">360.0</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:612.00px" class="cls_004"><span class="cls_004">If the new value of the </span><span class="cls_007">Value</span><span class="cls_004"> property is valid, then we calculate the</span></div>
<div style="position:absolute;left:5.00px;top:630.00px" class="cls_007"><span class="cls_007">scaledPercentageValue</span><span class="cls_004"> variable. We do this by first dividing the new value by the value of</span></div>
<div style="position:absolute;left:5.00px;top:648.00px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">MaximumValue</span><span class="cls_004"> property, to get the percentage of the maximum value. We then multiply</span></div>
<div style="position:absolute;left:5.00px;top:666.00px" class="cls_004"><span class="cls_004">that figure by </span><span class="cls_007">180</span><span class="cls_004"> </span><span class="cls_007">.0</span><span class="cls_004">, because our gauge covers a range of one hundred and eighty</span></div>
<div style="position:absolute;left:5.00px;top:684.00px" class="cls_004"><span class="cls_004">degrees.</span></div>
<div style="position:absolute;left:5.00px;top:702.00px" class="cls_004"><span class="cls_004">We then subtract the </span><span class="cls_007">scaledPercentageValue</span><span class="cls_004"> variable value from </span><span class="cls_007">180.0</span><span class="cls_004"> for the </span><span class="cls_007">ValueAngle</span></div>
<div style="position:absolute;left:5.00px;top:720.00px" class="cls_004"><span class="cls_004">property and add it to </span><span class="cls_007">180.0</span><span class="cls_004"> for the </span><span class="cls_007">RotationAngle</span><span class="cls_004"> property. This is because the</span></div>
<div style="position:absolute;left:5.00px;top:738.00px" class="cls_007"><span class="cls_007">ValueAngle</span><span class="cls_004"> property is used by our arc and needs to be between </span><span class="cls_007">180.0</span><span class="cls_004"> and </span><span class="cls_007">0.0</span><span class="cls_004"> and the</span></div>
<div style="position:absolute;left:5.00px;top:756.00px" class="cls_007"><span class="cls_007">RotationAngle</span><span class="cls_004"> property is used by our gauge needle and needs to be between </span><span class="cls_007">180.0</span><span class="cls_004"> and</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:242204px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background304.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_007"><span class="cls_007">360.0</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">This will soon be made clearer, so let's now see how we use these properties and the </span><span class="cls_007">Arc</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">control in our </span><span class="cls_007">Gauge</span><span class="cls_004"> control's default style from the </span><span class="cls_007">Generic.xaml</span><span class="cls_004"> file:</span></div>
<div style="position:absolute;left:52.98px;top:63.00px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type CustomControls:Gauge}"></span></div>
<div style="position:absolute;left:67.97px;top:76.50px" class="cls_007"><span class="cls_007"><Setter Property="Template"></span></div>
<div style="position:absolute;left:82.97px;top:90.00px" class="cls_007"><span class="cls_007"><Setter.Value></span></div>
<div style="position:absolute;left:97.96px;top:103.50px" class="cls_007"><span class="cls_007"><ControlTemplate TargetType="{x:Type CustomControls:Gauge}"></span></div>
<div style="position:absolute;left:112.96px;top:117.00px" class="cls_007"><span class="cls_007"><Grid Background="{Binding Background,</span></div>
<div style="position:absolute;left:127.95px;top:130.50px" class="cls_007"><span class="cls_007">RelativeSource={RelativeSource TemplatedParent}}"></span></div>
<div style="position:absolute;left:127.95px;top:144.00px" class="cls_007"><span class="cls_007"><Grid Margin="{Binding Padding,</span></div>
<div style="position:absolute;left:142.94px;top:157.50px" class="cls_007"><span class="cls_007">RelativeSource={RelativeSource TemplatedParent}}"></span></div>
<div style="position:absolute;left:142.94px;top:171.00px" class="cls_007"><span class="cls_007"><Grid.RowDefinitions></span></div>
<div style="position:absolute;left:157.94px;top:184.50px" class="cls_007"><span class="cls_007"><RowDefinition Height="Auto" /></span></div>
<div style="position:absolute;left:157.94px;top:198.00px" class="cls_007"><span class="cls_007"><RowDefinition /></span></div>
<div style="position:absolute;left:157.94px;top:211.50px" class="cls_007"><span class="cls_007"><RowDefinition Height="Auto" /></span></div>
<div style="position:absolute;left:142.94px;top:225.00px" class="cls_007"><span class="cls_007"></Grid.RowDefinitions></span></div>
<div style="position:absolute;left:142.94px;top:238.50px" class="cls_007"><span class="cls_007"><TextBlock Text="{Binding Title,</span></div>
<div style="position:absolute;left:157.94px;top:252.00px" class="cls_007"><span class="cls_007">RelativeSource={RelativeSource TemplatedParent}}"</span></div>
<div style="position:absolute;left:157.94px;top:265.50px" class="cls_007"><span class="cls_007">HorizontalAlignment="Center" /></span></div>
<div style="position:absolute;left:142.94px;top:279.00px" class="cls_007"><span class="cls_007"><Canvas Grid.Row="1" Width="300" Height="150"</span></div>
<div style="position:absolute;left:157.94px;top:292.50px" class="cls_007"><span class="cls_007">HorizontalAlignment="Center" Margin="0,5"></span></div>
<div style="position:absolute;left:157.94px;top:306.00px" class="cls_007"><span class="cls_007"><CustomControls:Arc Width="300" Height="300"</span></div>
<div style="position:absolute;left:172.93px;top:319.50px" class="cls_007"><span class="cls_007">StrokeThickness="75" Stroke="#FF444444" /></span></div>
<div style="position:absolute;left:157.94px;top:333.00px" class="cls_007"><span class="cls_007"><CustomControls:Arc Width="300" Height="300"</span></div>
<div style="position:absolute;left:172.93px;top:346.50px" class="cls_007"><span class="cls_007">StrokeThickness="75" Stroke="OrangeRed"</span></div>
<div style="position:absolute;left:52.98px;top:360.00px" class="cls_007"><span class="cls_007">StartAngle="180"</span></div>
<div style="position:absolute;left:172.93px;top:373.50px" class="cls_007"><span class="cls_007">EndAngle="{Binding AngleValue,</span></div>
<div style="position:absolute;left:172.93px;top:387.00px" class="cls_007"><span class="cls_007">RelativeSource={RelativeSource TemplatedParent}}"</span></div>
<div style="position:absolute;left:52.98px;top:400.50px" class="cls_007"><span class="cls_007">/></span></div>
<div style="position:absolute;left:157.94px;top:414.00px" class="cls_007"><span class="cls_007"><Path Canvas.Left="150" Canvas.Top="140"</span></div>
<div style="position:absolute;left:172.93px;top:427.50px" class="cls_007"><span class="cls_007">Fill="White" StrokeThickness="5" Stroke="White"</span></div>
<div style="position:absolute;left:172.93px;top:441.00px" class="cls_007"><span class="cls_007">StrokeLineJoin="Round" Data="M0,0 L125,10, 0,20Z"</span></div>
<div style="position:absolute;left:172.93px;top:454.50px" class="cls_007"><span class="cls_007">Stretch="Fill" Width="125" Height="20"></span></div>
<div style="position:absolute;left:172.93px;top:468.00px" class="cls_007"><span class="cls_007"><Path.RenderTransform></span></div>
<div style="position:absolute;left:187.92px;top:481.50px" class="cls_007"><span class="cls_007"><RotateTransform Angle="{Binding RotationAngle,</span></div>
<div style="position:absolute;left:202.92px;top:495.00px" class="cls_007"><span class="cls_007">RelativeSource={RelativeSource</span></div>
<div style="position:absolute;left:52.98px;top:508.50px" class="cls_007"><span class="cls_007">TemplatedParent}}"</span></div>
<div style="position:absolute;left:202.92px;top:522.00px" class="cls_007"><span class="cls_007">CenterX="0" CenterY="10" /></span></div>
<div style="position:absolute;left:172.93px;top:535.50px" class="cls_007"><span class="cls_007"></Path.RenderTransform></span></div>
<div style="position:absolute;left:157.94px;top:549.00px" class="cls_007"><span class="cls_007"></Path></span></div>
<div style="position:absolute;left:142.94px;top:562.50px" class="cls_007"><span class="cls_007"></Canvas></span></div>
<div style="position:absolute;left:142.94px;top:576.00px" class="cls_007"><span class="cls_007"><TextBlock Grid.Row="2" Text="{Binding Value,</span></div>
<div style="position:absolute;left:52.98px;top:589.50px" class="cls_007"><span class="cls_007">StringFormat=N0,</span></div>
<div style="position:absolute;left:157.94px;top:603.00px" class="cls_007"><span class="cls_007">RelativeSource={RelativeSource TemplatedParent}}"</span></div>
<div style="position:absolute;left:157.94px;top:616.50px" class="cls_007"><span class="cls_007">HorizontalAlignment="Center" FontWeight="Bold" /></span></div>
<div style="position:absolute;left:127.95px;top:630.00px" class="cls_007"><span class="cls_007"></Grid></span></div>
<div style="position:absolute;left:112.96px;top:643.50px" class="cls_007"><span class="cls_007"></Grid></span></div>
<div style="position:absolute;left:97.96px;top:657.00px" class="cls_007"><span class="cls_007"></ControlTemplate></span></div>
<div style="position:absolute;left:82.97px;top:670.50px" class="cls_007"><span class="cls_007"></Setter.Value></span></div>
<div style="position:absolute;left:67.97px;top:684.00px" class="cls_007"><span class="cls_007"></Setter></span></div>
<div style="position:absolute;left:52.98px;top:697.50px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:5.00px;top:717.75px" class="cls_004"><span class="cls_004">We start our default style as usual, by specifying the type of our control in both the style</span></div>
<div style="position:absolute;left:5.00px;top:735.75px" class="cls_004"><span class="cls_004">and the control template. Inside the template, we have two </span><span class="cls_007">Grid</span><span class="cls_004"> panels and data bind the</span></div>
<div style="position:absolute;left:5.00px;top:753.75px" class="cls_007"><span class="cls_007">Background</span><span class="cls_004"> of the outer panel and the </span><span class="cls_007">Margin</span><span class="cls_004"> property of the inner panel to properties of</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:243006px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background305.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">our templated control, so that users can set them externally.</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">We then define three rows in our inner panel. The control's </span><span class="cls_007">Title</span><span class="cls_004"> property is data bound to</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">a horizontally centered </span><span class="cls_007">TextBlock</span><span class="cls_004"> element in the first row. In the second row, we declare a</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">horizontally centered </span><span class="cls_007">Canvas</span><span class="cls_004"> panel that contains two of our new </span><span class="cls_007">Arc</span><span class="cls_004"> controls and a </span><span class="cls_007">Path</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">object.</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">The first </span><span class="cls_007">Arc</span><span class="cls_004"> control is gray and represents the background track that the </span><span class="cls_007">Arc</span><span class="cls_004"> that</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">represents our </span><span class="cls_007">Gauge</span><span class="cls_004"> control's </span><span class="cls_007">Value</span><span class="cls_004"> property sits on. The second </span><span class="cls_007">Arc</span><span class="cls_004"> control is colored</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_007"><span class="cls_007">OrangeRed</span><span class="cls_004"> and displays the current value of our </span><span class="cls_007">Gauge</span><span class="cls_004"> control's </span><span class="cls_007">Value</span><span class="cls_004"> property, by data</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">binding its </span><span class="cls_007">EndAngle</span><span class="cls_004"> property to the </span><span class="cls_007">AngleValue</span><span class="cls_004"> Dependency Property of the </span><span class="cls_007">Gauge</span><span class="cls_004"> control.</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">Note that the angles in our </span><span class="cls_007">Arc</span><span class="cls_004"> control follow the common Cartesian coordinate system,</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">with an angle of zero degrees falling to the right and increasing values moving anti-</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">clockwise. Therefore, to draw a semi-circular arc from left to right, we start with an angle</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">of </span><span class="cls_007">180</span><span class="cls_004"> degrees and end at </span><span class="cls_007">0</span><span class="cls_004"> degrees, as demonstrated by the background arc in our </span><span class="cls_007">Gauge</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">control.</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">Furthermore, our </span><span class="cls_007">Arc</span><span class="cls_004"> controls have the same width and height values, but as we don't need</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">their lower halves, we crop them using the height of the canvas panel. The </span><span class="cls_007">Path</span><span class="cls_004"> object</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">represents the gauge needle in our control and is painted white.</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">We set the </span><span class="cls_007">StrokeLineJoin</span><span class="cls_004"> property to the </span><span class="cls_007">Round</span><span class="cls_004"> value in order to curve the three corners,</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_004"><span class="cls_004">where the lines of the needle path meet. Note that the needle is positioned exactly half way</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_004"><span class="cls_004">across the width of the canvas and ten pixels above the bottom, to enable its center line to</span></div>
<div style="position:absolute;left:5.00px;top:363.75px" class="cls_004"><span class="cls_004">lie along the bottom of the canvas.</span></div>
<div style="position:absolute;left:5.00px;top:381.75px" class="cls_004"><span class="cls_004">Rather than declaring </span><span class="cls_007">PathFigure</span><span class="cls_004"> and </span><span class="cls_007">LineSegment</span><span class="cls_004"> objects to define the needle, we have</span></div>
<div style="position:absolute;left:5.00px;top:399.75px" class="cls_004"><span class="cls_004">used the shorthand notation inline in the </span><span class="cls_007">Data</span><span class="cls_004"> property. The </span><span class="cls_007">M</span><span class="cls_004"> specifies that we should move</span></div>
<div style="position:absolute;left:5.00px;top:417.75px" class="cls_004"><span class="cls_004">to (or start from) the point </span><span class="cls_007">0</span><span class="cls_004">, </span><span class="cls_007">0</span><span class="cls_004">, the </span><span class="cls_007">L</span><span class="cls_004"> specifies that we want to draw a line to the point </span><span class="cls_007">125</span><span class="cls_004">,</span></div>
<div style="position:absolute;left:5.00px;top:435.75px" class="cls_007"><span class="cls_007">10</span><span class="cls_004"> and then from there to the point </span><span class="cls_007">0</span><span class="cls_004">, </span><span class="cls_007">20</span><span class="cls_004"> and the </span><span class="cls_007">Z</span><span class="cls_004"> means that we want to close the path by</span></div>
<div style="position:absolute;left:5.00px;top:453.75px" class="cls_004"><span class="cls_004">joining the first and last points.</span></div>
<div style="position:absolute;left:5.00px;top:471.75px" class="cls_004"><span class="cls_004">We then set the width and height of the path to the same values that were declared within</span></div>
<div style="position:absolute;left:5.00px;top:489.75px" class="cls_004"><span class="cls_004">its </span><span class="cls_007">Data</span><span class="cls_004"> property. Now, the essential part of enabling this needle to point to the relevant</span></div>
<div style="position:absolute;left:5.00px;top:507.75px" class="cls_004"><span class="cls_004">position to reflect the data bound </span><span class="cls_007">Value</span><span class="cls_004"> property, is the </span><span class="cls_007">RotateTransform</span><span class="cls_004"> object that is</span></div>
<div style="position:absolute;left:5.00px;top:525.75px" class="cls_004"><span class="cls_004">applied to the path's </span><span class="cls_007">RenderTransform</span><span class="cls_004"> property. Note that its center point is set to be the</span></div>
<div style="position:absolute;left:5.00px;top:543.75px" class="cls_004"><span class="cls_004">center of the bottom of the needle, as that is the point that we want to rotate from.</span></div>
<div style="position:absolute;left:5.00px;top:561.75px" class="cls_004"><span class="cls_004">As the </span><span class="cls_007">RotateTransform</span><span class="cls_004"> object rotates clockwise with increasing </span><span class="cls_007">Angle</span><span class="cls_004"> values, we cannot</span></div>
<div style="position:absolute;left:5.00px;top:579.75px" class="cls_004"><span class="cls_004">reuse the </span><span class="cls_007">AngleValue</span><span class="cls_004"> Dependency Property with it. Therefore, in this particular example,</span></div>
<div style="position:absolute;left:5.00px;top:597.75px" class="cls_004"><span class="cls_004">we define the needle pointing to the right and use a range of </span><span class="cls_007">180</span><span class="cls_004"> </span><span class="cls_007">.0</span><span class="cls_004"> to </span><span class="cls_007">360</span><span class="cls_004"> </span><span class="cls_007">.0</span><span class="cls_004"> degrees in</span></div>
<div style="position:absolute;left:5.00px;top:615.75px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">RotationAngle</span><span class="cls_004"> read-only Dependency Property with the transform object to match the</span></div>
<div style="position:absolute;left:5.00px;top:633.75px" class="cls_004"><span class="cls_004">position of the value arc.</span></div>
<div style="position:absolute;left:5.00px;top:651.75px" class="cls_004"><span class="cls_004">At the end of the example, we see another horizontally centered</span><span class="cls_007"> TextBlock</span><span class="cls_004"> element, that</span></div>
<div style="position:absolute;left:5.00px;top:669.75px" class="cls_004"><span class="cls_004">outputs the current, unaltered value of the data bound </span><span class="cls_007">Value</span><span class="cls_004"> Dependency Property. Note</span></div>
<div style="position:absolute;left:5.00px;top:687.75px" class="cls_004"><span class="cls_004">that we use the </span><span class="cls_007">StringFormat</span><span class="cls_004"> value of </span><span class="cls_007">N0</span><span class="cls_004"> to remove the decimal places from the value</span></div>
<div style="position:absolute;left:5.00px;top:705.75px" class="cls_004"><span class="cls_004">before displaying it.</span></div>
<div style="position:absolute;left:5.00px;top:723.75px" class="cls_004"><span class="cls_004">That completes our new </span><span class="cls_007">Gauge</span><span class="cls_004"> control and so, all we need to do now is see how we can</span></div>
<div style="position:absolute;left:5.00px;top:741.75px" class="cls_004"><span class="cls_004">use it.</span></div>
<div style="position:absolute;left:52.98px;top:765.00px" class="cls_007"><span class="cls_007"><CustomControls:Gauge Width="400" Height="300"</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:243808px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background306.jpg" width=612 height=792></div>
<div style="position:absolute;left:67.97px;top:3.00px" class="cls_007"><span class="cls_007">MaximumValue="{Binding InCount}" Value="{Binding OutCount}"</span></div>
<div style="position:absolute;left:67.97px;top:16.50px" class="cls_007"><span class="cls_007">Title="Success Percentage" Foreground="White" FontSize="34"</span></div>
<div style="position:absolute;left:67.97px;top:30.00px" class="cls_007"><span class="cls_007">Padding="10" /></span></div>
<div style="position:absolute;left:5.00px;top:50.25px" class="cls_004"><span class="cls_004">We could extend our new </span><span class="cls_007">Gauge</span><span class="cls_004"> control to make it more usable in several ways. We could</span></div>
<div style="position:absolute;left:5.00px;top:68.25px" class="cls_004"><span class="cls_004">add a </span><span class="cls_007">MinimumValue</span><span class="cls_004"> Dependency Property to enable its use with value ranges that do not</span></div>
<div style="position:absolute;left:5.00px;top:86.25px" class="cls_004"><span class="cls_004">start at zero, or we could expose further properties to enable users to color, size, or further</span></div>
<div style="position:absolute;left:5.00px;top:104.25px" class="cls_004"><span class="cls_004">customize the control. Alternatively, we could rewrite it to enable it to be any size, instead of</span></div>
<div style="position:absolute;left:5.00px;top:122.25px" class="cls_004"><span class="cls_004">hard coding sizes as we did.</span></div>
<div style="position:absolute;left:5.00px;top:139.51px" class="cls_011"><span class="cls_011">Livening up UI controls</span></div>
<div style="position:absolute;left:5.00px;top:169.50px" class="cls_004"><span class="cls_004">In addition to making our UI controls look visually appealing, we can also 'liven them up' by</span></div>
<div style="position:absolute;left:5.00px;top:187.50px" class="cls_004"><span class="cls_004">adding user interactivity in the form of mouse over effects. While most mouse over effects</span></div>
<div style="position:absolute;left:5.00px;top:205.50px" class="cls_004"><span class="cls_004">are created using </span><span class="cls_007">Trigger</span><span class="cls_004"> and </span><span class="cls_007">Setter</span><span class="cls_004"> objects, that immediately update the relevant style</span></div>
<div style="position:absolute;left:5.00px;top:223.50px" class="cls_004"><span class="cls_004">properties when the related trigger condition is met, we can alternatively use animations to</span></div>
<div style="position:absolute;left:5.00px;top:241.50px" class="cls_004"><span class="cls_004">produce these effects.</span></div>
<div style="position:absolute;left:5.00px;top:259.50px" class="cls_004"><span class="cls_004">Having even subtle transitions between states, rather than instantly switching, can also</span></div>
<div style="position:absolute;left:5.00px;top:277.50px" class="cls_004"><span class="cls_004">provide a richer user experience. Let's reuse our initial double bordered example from</span></div>
<div style="position:absolute;left:5.00px;top:295.50px" class="cls_004"><span class="cls_004">earlier and add some mouse interactivity animations to it to demonstrate this point. We'll</span></div>
<div style="position:absolute;left:5.00px;top:313.50px" class="cls_004"><span class="cls_004">need to add a few more resources into a suitable resource collection and adjust a couple of</span></div>
<div style="position:absolute;left:5.00px;top:331.50px" class="cls_004"><span class="cls_004">our previously declared resources too.</span></div>
<div style="position:absolute;left:52.98px;top:354.75px" class="cls_007"><span class="cls_007"><Color x:Key="TransparentWhiteColor" A="127" R="255" G="255"</span></div>
<div style="position:absolute;left:52.98px;top:368.25px" class="cls_007"><span class="cls_007">B="255" /></span></div>
<div style="position:absolute;left:52.98px;top:381.75px" class="cls_007"><span class="cls_007"><Color x:Key="TransparentBlackColor" A="127" R="0" G="0" B="0" /></span></div>
<div style="position:absolute;left:5.00px;top:402.00px" class="cls_004"><span class="cls_004">Now that we have declared our semi-transparent </span><span class="cls_007">Color</span><span class="cls_004"> resources, we can adjust our</span></div>
<div style="position:absolute;left:5.00px;top:420.00px" class="cls_004"><span class="cls_004">earlier brush resources to utilize them.</span></div>
<div style="position:absolute;left:52.98px;top:443.25px" class="cls_007"><span class="cls_007"><SolidColorBrush x:Key="TransparentWhite"</span></div>
<div style="position:absolute;left:67.97px;top:456.75px" class="cls_007"><span class="cls_007">Color="{StaticResource TransparentWhiteColor}" /></span></div>
<div style="position:absolute;left:52.98px;top:470.25px" class="cls_007"><span class="cls_007"><SolidColorBrush x:Key="TransparentBlack"</span></div>
<div style="position:absolute;left:67.97px;top:483.75px" class="cls_007"><span class="cls_007">Color="{StaticResource TransparentBlackColor}" /></span></div>
<div style="position:absolute;left:5.00px;top:504.00px" class="cls_004"><span class="cls_004">Let's see our full example now.</span></div>
<div style="position:absolute;left:52.98px;top:527.25px" class="cls_007"><span class="cls_007"><Grid Width="160" Height="68"></span></div>
<div style="position:absolute;left:67.97px;top:540.75px" class="cls_007"><span class="cls_007"><Grid.Background></span></div>
<div style="position:absolute;left:82.97px;top:554.25px" class="cls_007"><span class="cls_007"><LinearGradientBrush StartPoint="0,0" EndPoint="1,1"></span></div>
<div style="position:absolute;left:97.96px;top:567.75px" class="cls_007"><span class="cls_007"><GradientStop Color="Red" /></span></div>
<div style="position:absolute;left:97.96px;top:581.25px" class="cls_007"><span class="cls_007"><GradientStop Color="Yellow" Offset="1" /></span></div>
<div style="position:absolute;left:82.97px;top:594.75px" class="cls_007"><span class="cls_007"></LinearGradientBrush></span></div>
<div style="position:absolute;left:67.97px;top:608.25px" class="cls_007"><span class="cls_007"></Grid.Background></span></div>
<div style="position:absolute;left:67.97px;top:621.75px" class="cls_007"><span class="cls_007"><Button Content="Click Me" Width="120" Height="28" FontSize="14"</span></div>
<div style="position:absolute;left:82.97px;top:635.25px" class="cls_007"><span class="cls_007">Margin="20"></span></div>
<div style="position:absolute;left:82.97px;top:648.75px" class="cls_007"><span class="cls_007"><Button.Template></span></div>
<div style="position:absolute;left:97.96px;top:662.25px" class="cls_007"><span class="cls_007"><ControlTemplate TargetType="{x:Type Button}"></span></div>
<div style="position:absolute;left:112.96px;top:675.75px" class="cls_007"><span class="cls_007"><Border Name="OuterBorder"</span></div>
<div style="position:absolute;left:127.95px;top:689.25px" class="cls_007"><span class="cls_007">BorderBrush="{StaticResource TransparentBlack}"</span></div>
<div style="position:absolute;left:127.95px;top:702.75px" class="cls_007"><span class="cls_007">BorderThickness="1" Padding="1"</span></div>
<div style="position:absolute;left:127.95px;top:716.25px" class="cls_007"><span class="cls_007">Background="{StaticResource TransparentWhite}"</span></div>
<div style="position:absolute;left:127.95px;top:729.75px" class="cls_007"><span class="cls_007">CornerRadius="5" SnapsToDevicePixels="True"></span></div>
<div style="position:absolute;left:127.95px;top:743.25px" class="cls_007"><span class="cls_007"><Border Name="InnerBorder"</span></div>
<div style="position:absolute;left:142.94px;top:756.75px" class="cls_007"><span class="cls_007">BorderBrush="{StaticResource TransparentBlack}"</span></div>
<div style="position:absolute;left:142.94px;top:770.25px" class="cls_007"><span class="cls_007">BorderThickness="1" Background="White"</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:244610px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background307.jpg" width=612 height=792></div>
<div style="position:absolute;left:142.94px;top:3.00px" class="cls_007"><span class="cls_007">CornerRadius="3.5" SnapsToDevicePixels="True"></span></div>
<div style="position:absolute;left:142.94px;top:16.50px" class="cls_007"><span class="cls_007"><ContentPresenter HorizontalAlignment="Center"</span></div>
<div style="position:absolute;left:157.94px;top:30.00px" class="cls_007"><span class="cls_007">VerticalAlignment="Center" /></span></div>
<div style="position:absolute;left:127.95px;top:43.50px" class="cls_007"><span class="cls_007"></Border></span></div>
<div style="position:absolute;left:112.96px;top:57.00px" class="cls_007"><span class="cls_007"></Border></span></div>
<div style="position:absolute;left:112.96px;top:70.50px" class="cls_007"><span class="cls_007"><ControlTemplate.Triggers></span></div>
<div style="position:absolute;left:127.95px;top:84.00px" class="cls_007"><span class="cls_007"><Trigger Property="IsMouseOver" Value="True"></span></div>
<div style="position:absolute;left:142.94px;top:97.50px" class="cls_007"><span class="cls_007"><Trigger.EnterActions></span></div>
<div style="position:absolute;left:157.94px;top:111.00px" class="cls_007"><span class="cls_007"><BeginStoryboard></span></div>
<div style="position:absolute;left:172.93px;top:124.50px" class="cls_007"><span class="cls_007"><Storyboard Storyboard.TargetName="OuterBorder"</span></div>
<div style="position:absolute;left:187.92px;top:138.00px" class="cls_007"><span class="cls_007">Storyboard.TargetProperty=</span></div>
<div style="position:absolute;left:187.92px;top:151.50px" class="cls_007"><span class="cls_007">"BorderBrush.(SolidColorBrush.Color)"></span></div>
<div style="position:absolute;left:187.92px;top:165.00px" class="cls_007"><span class="cls_007"><ColorAnimation To="Black" Duration="0:0:0.25" /></span></div>
<div style="position:absolute;left:172.93px;top:178.50px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:157.94px;top:192.00px" class="cls_007"><span class="cls_007"></BeginStoryboard></span></div>
<div style="position:absolute;left:157.94px;top:205.50px" class="cls_007"><span class="cls_007"><BeginStoryboard></span></div>
<div style="position:absolute;left:172.93px;top:219.00px" class="cls_007"><span class="cls_007"><Storyboard Storyboard.TargetName="InnerBorder"</span></div>
<div style="position:absolute;left:187.92px;top:232.50px" class="cls_007"><span class="cls_007">Storyboard.TargetProperty=</span></div>
<div style="position:absolute;left:187.92px;top:246.00px" class="cls_007"><span class="cls_007">"BorderBrush.(SolidColorBrush.Color)"></span></div>
<div style="position:absolute;left:187.92px;top:259.50px" class="cls_007"><span class="cls_007"><ColorAnimation To="Black" Duration="0:0:0.3" /></span></div>
<div style="position:absolute;left:172.93px;top:273.00px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:157.94px;top:286.50px" class="cls_007"><span class="cls_007"></BeginStoryboard></span></div>
<div style="position:absolute;left:157.94px;top:300.00px" class="cls_007"><span class="cls_007"><BeginStoryboard Name="BackgroundFadeIn"</span></div>
<div style="position:absolute;left:172.93px;top:313.50px" class="cls_007"><span class="cls_007">HandoffBehavior="Compose"></span></div>
<div style="position:absolute;left:172.93px;top:327.00px" class="cls_007"><span class="cls_007"><Storyboard Storyboard.TargetName="InnerBorder"</span></div>
<div style="position:absolute;left:187.92px;top:340.50px" class="cls_007"><span class="cls_007">Storyboard.TargetProperty=</span></div>
<div style="position:absolute;left:187.92px;top:354.00px" class="cls_007"><span class="cls_007">"Background.(SolidColorBrush.Color)"></span></div>
<div style="position:absolute;left:187.92px;top:367.50px" class="cls_007"><span class="cls_007"><ColorAnimation To="{StaticResource</span></div>
<div style="position:absolute;left:202.92px;top:381.00px" class="cls_007"><span class="cls_007">TransparentWhiteColor}" Duration="0:0:0.2" /></span></div>
<div style="position:absolute;left:172.93px;top:394.50px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:157.94px;top:408.00px" class="cls_007"><span class="cls_007"></BeginStoryboard></span></div>
<div style="position:absolute;left:142.94px;top:421.50px" class="cls_007"><span class="cls_007"></Trigger.EnterActions></span></div>
<div style="position:absolute;left:142.94px;top:435.00px" class="cls_007"><span class="cls_007"><Trigger.ExitActions></span></div>
<div style="position:absolute;left:157.94px;top:448.50px" class="cls_007"><span class="cls_007"><BeginStoryboard></span></div>
<div style="position:absolute;left:172.93px;top:462.00px" class="cls_007"><span class="cls_007"><Storyboard Storyboard.TargetName="OuterBorder"</span></div>
<div style="position:absolute;left:187.92px;top:475.50px" class="cls_007"><span class="cls_007">Storyboard.TargetProperty=</span></div>
<div style="position:absolute;left:187.92px;top:489.00px" class="cls_007"><span class="cls_007">"BorderBrush.(SolidColorBrush.Color)"></span></div>
<div style="position:absolute;left:187.92px;top:502.50px" class="cls_007"><span class="cls_007"><ColorAnimation To="{StaticResource</span></div>
<div style="position:absolute;left:202.92px;top:516.00px" class="cls_007"><span class="cls_007">TransparentBlackColor}" Duration="0:0:0.5" /></span></div>
<div style="position:absolute;left:172.93px;top:529.50px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:157.94px;top:543.00px" class="cls_007"><span class="cls_007"></BeginStoryboard></span></div>
<div style="position:absolute;left:157.94px;top:556.50px" class="cls_007"><span class="cls_007"><BeginStoryboard></span></div>
<div style="position:absolute;left:172.93px;top:570.00px" class="cls_007"><span class="cls_007"><Storyboard Storyboard.TargetName="InnerBorder"</span></div>
<div style="position:absolute;left:187.92px;top:583.50px" class="cls_007"><span class="cls_007">Storyboard.TargetProperty=</span></div>
<div style="position:absolute;left:187.92px;top:597.00px" class="cls_007"><span class="cls_007">"BorderBrush.(SolidColorBrush.Color)"></span></div>
<div style="position:absolute;left:187.92px;top:610.50px" class="cls_007"><span class="cls_007"><ColorAnimation To="{StaticResource</span></div>
<div style="position:absolute;left:202.92px;top:624.00px" class="cls_007"><span class="cls_007">TransparentBlackColor}" Duration="0:0:0.3" /></span></div>
<div style="position:absolute;left:172.93px;top:637.50px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:157.94px;top:651.00px" class="cls_007"><span class="cls_007"></BeginStoryboard></span></div>
<div style="position:absolute;left:157.94px;top:664.50px" class="cls_007"><span class="cls_007"><BeginStoryboard Name="BackgroundFadeOut"</span></div>
<div style="position:absolute;left:172.93px;top:678.00px" class="cls_007"><span class="cls_007">HandoffBehavior="Compose"></span></div>
<div style="position:absolute;left:172.93px;top:691.50px" class="cls_007"><span class="cls_007"><Storyboard Storyboard.TargetName="InnerBorder"</span></div>
<div style="position:absolute;left:187.92px;top:705.00px" class="cls_007"><span class="cls_007">Storyboard.TargetProperty=</span></div>
<div style="position:absolute;left:187.92px;top:718.50px" class="cls_007"><span class="cls_007">"Background.(SolidColorBrush.Color)"></span></div>
<div style="position:absolute;left:187.92px;top:732.00px" class="cls_007"><span class="cls_007"><ColorAnimation To="White" Duration="0:0:0.4" /></span></div>
<div style="position:absolute;left:172.93px;top:745.50px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:157.94px;top:759.00px" class="cls_007"><span class="cls_007"></BeginStoryboard></span></div>
<div style="position:absolute;left:142.94px;top:772.50px" class="cls_007"><span class="cls_007"></Trigger.ExitActions></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:245412px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background308.jpg" width=612 height=792></div>
<div style="position:absolute;left:127.95px;top:3.00px" class="cls_007"><span class="cls_007"></Trigger></span></div>
<div style="position:absolute;left:127.95px;top:16.50px" class="cls_007"><span class="cls_007"><Trigger Property="IsPressed" Value="True"></span></div>
<div style="position:absolute;left:142.94px;top:30.00px" class="cls_007"><span class="cls_007"><Trigger.EnterActions></span></div>
<div style="position:absolute;left:157.94px;top:43.50px" class="cls_007"><span class="cls_007"><BeginStoryboard Name="MouseDownBackground"</span></div>
<div style="position:absolute;left:172.93px;top:57.00px" class="cls_007"><span class="cls_007">HandoffBehavior="Compose"></span></div>
<div style="position:absolute;left:172.93px;top:70.50px" class="cls_007"><span class="cls_007"><Storyboard Storyboard.TargetName="InnerBorder"</span></div>
<div style="position:absolute;left:187.92px;top:84.00px" class="cls_007"><span class="cls_007">Storyboard.TargetProperty=</span></div>
<div style="position:absolute;left:187.92px;top:97.50px" class="cls_007"><span class="cls_007">"Background.(SolidColorBrush.Color)"></span></div>
<div style="position:absolute;left:187.92px;top:111.00px" class="cls_007"><span class="cls_007"><ColorAnimation From="#D6FF21" Duration="0:0:1"</span></div>
<div style="position:absolute;left:202.92px;top:124.50px" class="cls_007"><span class="cls_007">DecelerationRatio="1.0" /></span></div>
<div style="position:absolute;left:172.93px;top:138.00px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:157.94px;top:151.50px" class="cls_007"><span class="cls_007"></BeginStoryboard></span></div>
<div style="position:absolute;left:142.94px;top:165.00px" class="cls_007"><span class="cls_007"></Trigger.EnterActions></span></div>
<div style="position:absolute;left:127.95px;top:178.50px" class="cls_007"><span class="cls_007"></Trigger></span></div>
<div style="position:absolute;left:127.95px;top:192.00px" class="cls_007"><span class="cls_007"><EventTrigger RoutedEvent="Unloaded"></span></div>
<div style="position:absolute;left:142.94px;top:205.50px" class="cls_007"><span class="cls_007"><RemoveStoryboard</span></div>
<div style="position:absolute;left:52.98px;top:219.00px" class="cls_007"><span class="cls_007">BeginStoryboardName="BackgroundFadeIn" /></span></div>
<div style="position:absolute;left:142.94px;top:232.50px" class="cls_007"><span class="cls_007"><RemoveStoryboard</span></div>
<div style="position:absolute;left:52.98px;top:246.00px" class="cls_007"><span class="cls_007">BeginStoryboardName="BackgroundFadeOut" /></span></div>
<div style="position:absolute;left:142.94px;top:259.50px" class="cls_007"><span class="cls_007"><RemoveStoryboard</span></div>
<div style="position:absolute;left:52.98px;top:273.00px" class="cls_007"><span class="cls_007">BeginStoryboardName="MouseDownBackground" /></span></div>
<div style="position:absolute;left:127.95px;top:286.50px" class="cls_007"><span class="cls_007"></EventTrigger></span></div>
<div style="position:absolute;left:112.96px;top:300.00px" class="cls_007"><span class="cls_007"></ControlTemplate.Triggers></span></div>
<div style="position:absolute;left:97.96px;top:313.50px" class="cls_007"><span class="cls_007"></ControlTemplate></span></div>
<div style="position:absolute;left:82.97px;top:327.00px" class="cls_007"><span class="cls_007"></Button.Template></span></div>
<div style="position:absolute;left:67.97px;top:340.50px" class="cls_007"><span class="cls_007"></Button></span></div>
<div style="position:absolute;left:52.98px;top:354.00px" class="cls_007"><span class="cls_007"></Grid></span></div>
<div style="position:absolute;left:5.00px;top:387.00px" class="cls_004"><span class="cls_004">While this example might seem quite long, it is actually fairly simple. We start with our</span></div>
<div style="position:absolute;left:5.00px;top:405.00px" class="cls_004"><span class="cls_004">original control template, albeit with the previously hardcoded brush values being replaced</span></div>
<div style="position:absolute;left:5.00px;top:423.00px" class="cls_004"><span class="cls_004">by our newly defined resources. The main difference to the original example is found in the</span></div>
<div style="position:absolute;left:5.00px;top:441.00px" class="cls_007"><span class="cls_007">ControlTemplate.Triggers</span><span class="cls_004"> collection.</span></div>
<div style="position:absolute;left:5.00px;top:459.00px" class="cls_004"><span class="cls_004">The first trigger will start its various storyboards when the </span><span class="cls_007">IsMouseOver</span><span class="cls_004"> property of the</span></div>
<div style="position:absolute;left:5.00px;top:477.00px" class="cls_007"><span class="cls_007">Button</span><span class="cls_004"> element is true, or in other words, when the user moves the mouse cursor over the</span></div>
<div style="position:absolute;left:5.00px;top:495.00px" class="cls_004"><span class="cls_004">button. Our storyboards are split between the </span><span class="cls_007">Trigger.EnterActions</span><span class="cls_004"> and</span></div>
<div style="position:absolute;left:5.00px;top:513.00px" class="cls_007"><span class="cls_007">Trigger.ExitActions</span><span class="cls_004"> collections.</span></div>
<div style="position:absolute;left:5.00px;top:531.00px" class="cls_004"><span class="cls_004">Remember that the storyboards in the </span><span class="cls_007">Trigger.EnterActions</span><span class="cls_004"> will be started as the mouse</span></div>
<div style="position:absolute;left:5.00px;top:549.00px" class="cls_004"><span class="cls_004">enters the bounds of the button, while the storyboards in the </span><span class="cls_007">Trigger.ExitActions</span><span class="cls_004"> will be</span></div>
<div style="position:absolute;left:5.00px;top:567.00px" class="cls_004"><span class="cls_004">started as the mouse leaves the bounds of the button. We declare three </span><span class="cls_007">BeginStoryboard</span></div>
<div style="position:absolute;left:5.00px;top:585.00px" class="cls_004"><span class="cls_004">objects with their associated </span><span class="cls_007">Storyboard</span><span class="cls_004"> objects within each of these</span></div>
<div style="position:absolute;left:5.00px;top:603.00px" class="cls_007"><span class="cls_007">TriggerActionCollection</span><span class="cls_004"> objects.</span></div>
<div style="position:absolute;left:5.00px;top:621.00px" class="cls_004"><span class="cls_004">The first animation targets the </span><span class="cls_007">BorderBrush</span><span class="cls_004"> property of the </span><span class="cls_007">OuterBorder</span><span class="cls_004"> element. Note that</span></div>
<div style="position:absolute;left:5.00px;top:639.00px" class="cls_004"><span class="cls_004">this property is of type </span><span class="cls_007">Brush</span><span class="cls_004">, but there is no </span><span class="cls_007">BrushAnimation</span><span class="cls_004"> class in WPF. Therefore, we</span></div>
<div style="position:absolute;left:5.00px;top:657.00px" class="cls_004"><span class="cls_004">need to target the </span><span class="cls_007">Color</span><span class="cls_004"> property of the </span><span class="cls_007">SolidColorBrush</span><span class="cls_004"> that is actually applied to this</span></div>
<div style="position:absolute;left:5.00px;top:675.00px" class="cls_004"><span class="cls_004">property and use a </span><span class="cls_007">ColorAnimation</span><span class="cls_004"> object instead.</span></div>
<div style="position:absolute;left:5.00px;top:693.00px" class="cls_004"><span class="cls_004">In order to do this, we need to use indirect targeting to first reference the </span><span class="cls_007">BorderBrush</span></div>
<div style="position:absolute;left:5.00px;top:711.00px" class="cls_004"><span class="cls_004">property and then to chain to the </span><span class="cls_007">Color</span><span class="cls_004"> property using the syntax </span><span class="cls_007">BorderBrush.</span></div>
<div style="position:absolute;left:5.00px;top:729.00px" class="cls_007"><span class="cls_007">(SolidColorBrush.Color)</span><span class="cls_004">. Note that this will only work if we are in fact using a</span></div>
<div style="position:absolute;left:5.00px;top:747.00px" class="cls_007"><span class="cls_007">SolidColorBrush</span><span class="cls_004"> element, as we are in this example.</span></div>
<div style="position:absolute;left:5.00px;top:765.00px" class="cls_004"><span class="cls_004">However, if we were using one of the gradient brushes instead of a </span><span class="cls_007">SolidColorBrush</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:246214px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background309.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">element, we could target the various colors of its </span><span class="cls_007">GradientStop</span><span class="cls_004"> elements with a slightly</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">different syntax. For example, we could target the color of the first </span><span class="cls_007">GradientStop</span><span class="cls_004"> element in</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">a gradient brush like this:</span></div>
<div style="position:absolute;left:52.98px;top:63.00px" class="cls_007"><span class="cls_007">BorderBrush.(GradientBrush.GradientStops)[0].(GradientStop.Color)</span></div>
<div style="position:absolute;left:5.00px;top:83.25px" class="cls_004"><span class="cls_004">Returning to this example now, the second animation targets the </span><span class="cls_007">BorderBrush</span><span class="cls_004"> property of</span></div>
<div style="position:absolute;left:5.00px;top:101.25px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">InnerBorder</span><span class="cls_004"> element and follows the syntactical example of the first animation. While</span></div>
<div style="position:absolute;left:5.00px;top:119.25px" class="cls_004"><span class="cls_004">the third animation also uses indirect targeting to reference the </span><span class="cls_007">Background</span><span class="cls_004"> property of the</span></div>
<div style="position:absolute;left:5.00px;top:137.25px" class="cls_007"><span class="cls_007">InnerBorder</span><span class="cls_004"> element, it is somewhat different to the other two animations.</span></div>
<div style="position:absolute;left:5.00px;top:155.25px" class="cls_004"><span class="cls_004">For this animation, we name the </span><span class="cls_007">BeginStoryboard</span><span class="cls_004"> object </span><span class="cls_007">BackgroundFadeIn</span><span class="cls_004"> and set its</span></div>
<div style="position:absolute;left:5.00px;top:173.25px" class="cls_007"><span class="cls_007">HandoffBehavior</span><span class="cls_004"> property to </span><span class="cls_007">Compose</span><span class="cls_004">, to enable smoother transitions between this and the</span></div>
<div style="position:absolute;left:5.00px;top:191.25px" class="cls_004"><span class="cls_004">other animations of this property. The specified name will be used later in the example.</span></div>
<div style="position:absolute;left:5.00px;top:209.25px" class="cls_004"><span class="cls_004">Note that these three </span><span class="cls_007">ColorAnimation</span><span class="cls_004"> objects only have their </span><span class="cls_007">To</span><span class="cls_004"> and </span><span class="cls_007">Duration</span><span class="cls_004"> properties</span></div>
<div style="position:absolute;left:5.00px;top:227.25px" class="cls_004"><span class="cls_004">set and that the three duration values are slightly different. This has the effect of slightly</span></div>
<div style="position:absolute;left:5.00px;top:245.25px" class="cls_004"><span class="cls_004">thickening the effect, although synchronizing the times also works well.</span></div>
<div style="position:absolute;left:5.00px;top:263.25px" class="cls_004"><span class="cls_004">We have omitted the </span><span class="cls_007">From</span><span class="cls_004"> values on these animations to avoid situations where the current</span></div>
<div style="position:absolute;left:5.00px;top:281.25px" class="cls_004"><span class="cls_004">animated colors do not match the </span><span class="cls_007">From</span><span class="cls_004"> values and have to immediately jump to the starting</span></div>
<div style="position:absolute;left:5.00px;top:299.25px" class="cls_004"><span class="cls_004">values before animating to the </span><span class="cls_007">To</span><span class="cls_004"> values. By omitting these values, the animations will start</span></div>
<div style="position:absolute;left:5.00px;top:317.25px" class="cls_004"><span class="cls_004">at their current color values and will result in smoother transitions.</span></div>
<div style="position:absolute;left:5.00px;top:335.25px" class="cls_004"><span class="cls_004">The three animations in the </span><span class="cls_007">Trigger.ExitActions</span><span class="cls_004"> collection are very similar to those in the</span></div>
<div style="position:absolute;left:5.00px;top:353.25px" class="cls_007"><span class="cls_007">EnterActions</span><span class="cls_004"> collection, albeit animating the colors back to their original starting colors, so</span></div>
<div style="position:absolute;left:5.00px;top:371.25px" class="cls_004"><span class="cls_004">we can skip their explanation here. However, it is worth highlighting the fact that the third</span></div>
<div style="position:absolute;left:5.00px;top:389.25px" class="cls_004"><span class="cls_004">animation is also declared in a named </span><span class="cls_007">BeginStoryboard</span><span class="cls_004"> that has its </span><span class="cls_007">HandoffBehavior</span></div>
<div style="position:absolute;left:5.00px;top:407.25px" class="cls_004"><span class="cls_004">property set to </span><span class="cls_007">Compose</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:425.25px" class="cls_004"><span class="cls_004">The next </span><span class="cls_007">Trigger</span><span class="cls_004"> object will start its associated storyboard when the </span><span class="cls_007">IsPressed</span><span class="cls_004"> property of</span></div>
<div style="position:absolute;left:5.00px;top:443.25px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">Button</span><span class="cls_004"> element is true and as it is declared within the </span><span class="cls_007">EnterActions</span><span class="cls_004"> collection, it will</span></div>
<div style="position:absolute;left:5.00px;top:461.25px" class="cls_004"><span class="cls_004">start when the user presses the mouse button down, rather than upon its release.</span></div>
<div style="position:absolute;left:5.00px;top:479.25px" class="cls_004"><span class="cls_004">This animation also uses indirect targeting to reference the </span><span class="cls_007">Background</span><span class="cls_004"> property of the</span></div>
<div style="position:absolute;left:5.00px;top:497.25px" class="cls_007"><span class="cls_007">InnerBorder</span><span class="cls_004"> element and also has a named </span><span class="cls_007">BeginStoryboard</span><span class="cls_004"> object with its</span></div>
<div style="position:absolute;left:5.00px;top:515.25px" class="cls_007"><span class="cls_007">HandoffBehavior</span><span class="cls_004"> property set to </span><span class="cls_007">Compose</span><span class="cls_004">. Unlike the other animations, this one has an</span></div>
<div style="position:absolute;left:5.00px;top:533.25px" class="cls_004"><span class="cls_004">extended duration and also sets the </span><span class="cls_007">DecelerationRatio</span><span class="cls_004"> property to </span><span class="cls_007">1.0</span><span class="cls_004">, which results in</span></div>
<div style="position:absolute;left:5.00px;top:551.25px" class="cls_004"><span class="cls_004">quick start and slow end.</span></div>
<div style="position:absolute;left:5.00px;top:569.25px" class="cls_004"><span class="cls_004">Finally, we reach the last trigger, which is an </span><span class="cls_007">EventTrigger</span><span class="cls_004"> object that will be triggered</span></div>
<div style="position:absolute;left:5.00px;top:587.25px" class="cls_004"><span class="cls_004">when the </span><span class="cls_007">Button</span><span class="cls_004"> object is unloaded. In this trigger, we remove the three named</span></div>
<div style="position:absolute;left:5.00px;top:605.25px" class="cls_004"><span class="cls_004">storyboards, thereby freeing the extra resources that they consume when using the </span><span class="cls_007">Compose</span></div>
<div style="position:absolute;left:5.00px;top:623.25px" class="cls_004"><span class="cls_004">handoff behavior. This was the sole purpose for naming the three </span><span class="cls_007">BeginStoryboard</span><span class="cls_004"> objects</span></div>
<div style="position:absolute;left:5.00px;top:641.25px" class="cls_004"><span class="cls_004">that reference the </span><span class="cls_007">Background</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:5.00px;top:659.25px" class="cls_004"><span class="cls_004">When animating mouse over effects on buttons, we are not restricted to simply changing</span></div>
<div style="position:absolute;left:5.00px;top:677.25px" class="cls_004"><span class="cls_004">the background and border colors. The more imaginative that we can be, the more our</span></div>
<div style="position:absolute;left:5.00px;top:695.25px" class="cls_004"><span class="cls_004">applications will stand out from the crowd.</span></div>
<div style="position:absolute;left:5.00px;top:713.25px" class="cls_004"><span class="cls_004">For example, rather than simply changing the background colour of the button, we can</span></div>
<div style="position:absolute;left:5.00px;top:731.25px" class="cls_004"><span class="cls_004">instead move the focal point of the gradient with the mouse. We'll need to use some code</span></div>
<div style="position:absolute;left:5.00px;top:749.25px" class="cls_004"><span class="cls_004">to do this, so we'll need to create another custom control to demonstrate this point. Let's</span></div>
<div style="position:absolute;left:5.00px;top:767.25px" class="cls_004"><span class="cls_004">first look at the code from our new custom control:</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:247016px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background310.jpg" width=612 height=792></div>
<div style="position:absolute;left:52.98px;top:7.50px" class="cls_007"><span class="cls_007">using System.Windows;</span></div>
<div style="position:absolute;left:52.98px;top:21.00px" class="cls_007"><span class="cls_007">using System.Windows.Controls;</span></div>
<div style="position:absolute;left:52.98px;top:34.50px" class="cls_007"><span class="cls_007">using System.Windows.Controls.Primitives;</span></div>
<div style="position:absolute;left:52.98px;top:48.00px" class="cls_007"><span class="cls_007">using System.Windows.Input;</span></div>
<div style="position:absolute;left:52.98px;top:61.50px" class="cls_007"><span class="cls_007">using System.Windows.Media;</span></div>
<div style="position:absolute;left:52.98px;top:75.00px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.CustomControls.Enums;</span></div>
<div style="position:absolute;left:52.98px;top:102.00px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.CustomControls</span></div>
<div style="position:absolute;left:52.98px;top:115.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:129.00px" class="cls_007"><span class="cls_007">[TemplatePart(Name = "PART_Root", Type = typeof(Grid))]</span></div>
<div style="position:absolute;left:67.97px;top:142.50px" class="cls_007"><span class="cls_007">public class GlowButton : ButtonBase</span></div>
<div style="position:absolute;left:67.97px;top:156.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:169.50px" class="cls_007"><span class="cls_007">private RadialGradientBrush glowBrush = null;</span></div>
<div style="position:absolute;left:82.97px;top:196.50px" class="cls_007"><span class="cls_007">static GlowButton()</span></div>
<div style="position:absolute;left:82.97px;top:210.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:223.50px" class="cls_007"><span class="cls_007">DefaultStyleKeyProperty.OverrideMetadata (typeof(GlowButton),</span></div>
<div style="position:absolute;left:112.96px;top:237.00px" class="cls_007"><span class="cls_007">new FrameworkPropertyMetadata(typeof(GlowButton)));</span></div>
<div style="position:absolute;left:82.97px;top:250.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:277.50px" class="cls_007"><span class="cls_007">public GlowMode GlowMode { get; set; } =</span></div>
<div style="position:absolute;left:52.98px;top:291.00px" class="cls_007"><span class="cls_007">GlowMode.FullCenterMovement;</span></div>
<div style="position:absolute;left:82.97px;top:318.00px" class="cls_007"><span class="cls_007">public static readonly DependencyProperty GlowColorProperty =</span></div>
<div style="position:absolute;left:97.96px;top:331.50px" class="cls_007"><span class="cls_007">DependencyProperty.Register(nameof(GlowColor), typeof(Color),</span></div>
<div style="position:absolute;left:97.96px;top:345.00px" class="cls_007"><span class="cls_007">typeof(GlowButton), new PropertyMetadata(</span></div>
<div style="position:absolute;left:97.96px;top:358.50px" class="cls_007"><span class="cls_007">Color.FromArgb(121, 71, 0, 255), OnGlowColorChanged));</span></div>
<div style="position:absolute;left:82.97px;top:385.50px" class="cls_007"><span class="cls_007">public Color GlowColor</span></div>
<div style="position:absolute;left:82.97px;top:399.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:412.50px" class="cls_007"><span class="cls_007">get { return (Color)GetValue(GlowColorProperty); }</span></div>
<div style="position:absolute;left:97.96px;top:426.00px" class="cls_007"><span class="cls_007">set { SetValue(GlowColorProperty, value); }</span></div>
<div style="position:absolute;left:82.97px;top:439.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:466.50px" class="cls_007"><span class="cls_007">private static void OnGlowColorChanged(</span></div>
<div style="position:absolute;left:97.96px;top:480.00px" class="cls_007"><span class="cls_007">DependencyObject dependencyObject,</span></div>
<div style="position:absolute;left:97.96px;top:493.50px" class="cls_007"><span class="cls_007">DependencyPropertyChangedEventArgs e)</span></div>
<div style="position:absolute;left:82.97px;top:507.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:52.98px;top:534.00px" class="cls_007"><span class="cls_007">((GlowButton)dependencyObject).SetGlowColor((Color)e.NewValue);</span></div>
<div style="position:absolute;left:82.97px;top:547.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:574.50px" class="cls_007"><span class="cls_007">public override void OnApplyTemplate()</span></div>
<div style="position:absolute;left:82.97px;top:588.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:601.50px" class="cls_007"><span class="cls_007">Grid rootGrid = GetTemplateChild("PART_Root") as Grid;</span></div>
<div style="position:absolute;left:97.96px;top:615.00px" class="cls_007"><span class="cls_007">if (rootGrid != null)</span></div>
<div style="position:absolute;left:97.96px;top:628.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:112.96px;top:642.00px" class="cls_007"><span class="cls_007">rootGrid.MouseMove += Grid_MouseMove;</span></div>
<div style="position:absolute;left:112.96px;top:655.50px" class="cls_007"><span class="cls_007">glowBrush =</span></div>
<div style="position:absolute;left:127.95px;top:669.00px" class="cls_007"><span class="cls_007">(RadialGradientBrush)rootGrid.FindResource("GlowBrush");</span></div>
<div style="position:absolute;left:112.96px;top:682.50px" class="cls_007"><span class="cls_007">SetGlowColor(GlowColor);</span></div>
<div style="position:absolute;left:97.96px;top:696.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:709.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:736.50px" class="cls_007"><span class="cls_007">private void SetGlowColor(Color value)</span></div>
<div style="position:absolute;left:82.97px;top:750.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:763.50px" class="cls_007"><span class="cls_007">GlowColor = Color.FromArgb(121, value.R, value.G, value.B);</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:247818px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background311.jpg" width=612 height=792></div>
<div style="position:absolute;left:97.96px;top:3.00px" class="cls_007"><span class="cls_007">if (glowBrush != null)</span></div>
<div style="position:absolute;left:97.96px;top:16.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:112.96px;top:30.00px" class="cls_007"><span class="cls_007">GradientStop gradientStop = glowBrush.GradientStops[2];</span></div>
<div style="position:absolute;left:112.96px;top:43.50px" class="cls_007"><span class="cls_007">gradientStop.Color = GlowColor;</span></div>
<div style="position:absolute;left:97.96px;top:57.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:70.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:97.50px" class="cls_007"><span class="cls_007">private void Grid_MouseMove(object sender, MouseEventArgs e)</span></div>
<div style="position:absolute;left:82.97px;top:111.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:124.50px" class="cls_007"><span class="cls_007">Grid grid = (Grid)sender;</span></div>
<div style="position:absolute;left:97.96px;top:138.00px" class="cls_007"><span class="cls_007">if (grid.IsMouseOver && glowBrush != null)</span></div>
<div style="position:absolute;left:97.96px;top:151.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:112.96px;top:165.00px" class="cls_007"><span class="cls_007">Point mousePosition = e.GetPosition(grid);</span></div>
<div style="position:absolute;left:112.96px;top:178.50px" class="cls_007"><span class="cls_007">double x = mousePosition.X / ActualWidth;</span></div>
<div style="position:absolute;left:112.96px;top:192.00px" class="cls_007"><span class="cls_007">double y = GlowMode != GlowMode.HorizontalCenterMovement ?</span></div>
<div style="position:absolute;left:127.95px;top:205.50px" class="cls_007"><span class="cls_007">mousePosition.Y / ActualHeight : glowBrush.Center.Y;</span></div>
<div style="position:absolute;left:112.96px;top:219.00px" class="cls_007"><span class="cls_007">glowBrush.Center = new Point(x, y);</span></div>
<div style="position:absolute;left:112.96px;top:232.50px" class="cls_007"><span class="cls_007">if (GlowMode == GlowMode.HorizontalCenterMovement)</span></div>
<div style="position:absolute;left:127.95px;top:246.00px" class="cls_007"><span class="cls_007">glowBrush.GradientOrigin =</span></div>
<div style="position:absolute;left:127.95px;top:259.50px" class="cls_007"><span class="cls_007">new Point(x, glowBrush.GradientOrigin.Y);</span></div>
<div style="position:absolute;left:112.96px;top:273.00px" class="cls_007"><span class="cls_007">else if (GlowMode == GlowMode.FullCenterMovement)</span></div>
<div style="position:absolute;left:127.95px;top:286.50px" class="cls_007"><span class="cls_007">glowBrush.GradientOrigin = new Point(x, y);</span></div>
<div style="position:absolute;left:97.96px;top:300.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:313.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:327.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:340.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:360.75px" class="cls_004"><span class="cls_004">We start as usual, by adding the relevant using references and declaring the </span><span class="cls_007">PART_RootGrid</span></div>
<div style="position:absolute;left:5.00px;top:378.75px" class="cls_004"><span class="cls_004">panel element as being a required part of the control template in the</span></div>
<div style="position:absolute;left:5.00px;top:396.75px" class="cls_007"><span class="cls_007">TemplatePartAttribute</span><span class="cls_004"> attribute. As our custom control is a button, we extend the</span></div>
<div style="position:absolute;left:5.00px;top:414.75px" class="cls_007"><span class="cls_007">ButtonBase</span><span class="cls_004"> class.</span></div>
<div style="position:absolute;left:5.00px;top:432.75px" class="cls_004"><span class="cls_004">Next, we define the </span><span class="cls_007">glowBrush</span><span class="cls_004"> field and set it to null. In the static constructor, we call the</span></div>
<div style="position:absolute;left:5.00px;top:450.75px" class="cls_007"><span class="cls_007">OverrideMetadata</span><span class="cls_004"> method to inform the Framework of where our control's default style is.</span></div>
<div style="position:absolute;left:5.00px;top:468.75px" class="cls_004"><span class="cls_004">We then declare a </span><span class="cls_007">GlowMode</span><span class="cls_004"> CLR property of type </span><span class="cls_007">GlowMode</span><span class="cls_004"> and set it to the default</span></div>
<div style="position:absolute;left:5.00px;top:486.75px" class="cls_007"><span class="cls_007">FullCenterMovement</span><span class="cls_004"> member. Let's see the members of this </span><span class="cls_007">GlowMode</span><span class="cls_004"> enumeration now.</span></div>
<div style="position:absolute;left:52.98px;top:510.00px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.CustomControls.Enums</span></div>
<div style="position:absolute;left:52.98px;top:523.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:537.00px" class="cls_007"><span class="cls_007">public enum GlowMode</span></div>
<div style="position:absolute;left:67.97px;top:550.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:564.00px" class="cls_007"><span class="cls_007">NoCenterMovement, HorizontalCenterMovement, FullCenterMovement</span></div>
<div style="position:absolute;left:67.97px;top:577.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:591.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:611.25px" class="cls_004"><span class="cls_004">Returning to our </span><span class="cls_007">GlowButton</span><span class="cls_004"> class, we also declare a </span><span class="cls_007">GlowColor</span><span class="cls_004"> Dependency Property and</span></div>
<div style="position:absolute;left:5.00px;top:629.25px" class="cls_004"><span class="cls_004">define a default purple color, a property changed handler and some CLR property wrappers</span></div>
<div style="position:absolute;left:5.00px;top:647.25px" class="cls_004"><span class="cls_004">for it. In the </span><span class="cls_007">OnGlowColorChanged</span><span class="cls_004"> handler method, we cast the </span><span class="cls_007">dependencyObject</span><span class="cls_004"> input</span></div>
<div style="position:absolute;left:5.00px;top:665.25px" class="cls_004"><span class="cls_004">parameter to our </span><span class="cls_007">GlowButton</span><span class="cls_004"> class and call the </span><span class="cls_007">SetGlowColor</span><span class="cls_004"> method, passing in the new</span></div>
<div style="position:absolute;left:5.00px;top:683.25px" class="cls_007"><span class="cls_007">Color</span><span class="cls_004"> input value.</span></div>
<div style="position:absolute;left:5.00px;top:701.25px" class="cls_004"><span class="cls_004">Next, we see the </span><span class="cls_007">OnApplyTemplate</span><span class="cls_004"> method that is called when the button element's control</span></div>
<div style="position:absolute;left:5.00px;top:719.25px" class="cls_004"><span class="cls_004">template has been applied. In this method, we attempt to access the </span><span class="cls_007">PART_Root</span><span class="cls_004"> panel</span></div>
<div style="position:absolute;left:5.00px;top:737.25px" class="cls_004"><span class="cls_004">element using the </span><span class="cls_007">GetTemplateChild</span><span class="cls_004"> method and check it for null. If it is not null, we do a</span></div>
<div style="position:absolute;left:5.00px;top:755.25px" class="cls_004"><span class="cls_004">number of things.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:248620px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background312.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">First, we attach the </span><span class="cls_007">Grid_MouseMove</span><span class="cls_004"> event handler method to the grid's </span><span class="cls_007">MouseMove</span><span class="cls_004"> event.</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">Note that this is the way to attach event handlers to the UI elements that are declared in the</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_007"><span class="cls_007">Generic</span><span class="cls_004"> </span><span class="cls_007">.xaml</span><span class="cls_004"> file, as it has no related code behind file.</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">Next, we call the grid's </span><span class="cls_007">FindResource</span><span class="cls_004"> method in order to access the </span><span class="cls_007">GlowBrush</span><span class="cls_004"> resource</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">from its </span><span class="cls_007">Resources</span><span class="cls_004"> section and set it to our local </span><span class="cls_007">glowBrush</span><span class="cls_004"> field, as we will be referencing</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">it regularly. After this, we call the </span><span class="cls_007">SetGlowColor</span><span class="cls_004"> method and pass in the current </span><span class="cls_007">GlowColor</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">value.</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">We do this because the </span><span class="cls_007">OnApplyTemplate</span><span class="cls_004"> method is generally called after the properties</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">have been set, but we are unable to update the brush resource until the template has been</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">applied. When writing custom controls, we often need to update properties from this</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">method, once the template has been applied.</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">Next is the </span><span class="cls_007">SetGlowColor</span><span class="cls_004"> method and in it, we first make the set color semi-transparent. If</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">glowBrush</span><span class="cls_004"> variable is not null, we then access the third </span><span class="cls_007">GradientStop</span><span class="cls_004"> element from its</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_007"><span class="cls_007">GradientStops</span><span class="cls_004"> collection and set its </span><span class="cls_007">Color</span><span class="cls_004"> property to the value of our </span><span class="cls_007">GlowColor</span><span class="cls_004"> property.</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">Note that the third </span><span class="cls_007">GradientStop</span><span class="cls_004"> element represents the dominant color in this gradient and</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">so in this example, we are only updating this single element, in order to save space in this</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">book. This gives the overall impression of a complete color change, but anyone that looks</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">carefully will be able to see a dash of purple showing through from the other two unchanged</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_007"><span class="cls_007">GradientStop</span><span class="cls_004"> elements. You may wish to extend this example to update the whole</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_007"><span class="cls_007">GradientStops</span><span class="cls_004"> collection.</span></div>
<div style="position:absolute;left:5.00px;top:363.75px" class="cls_004"><span class="cls_004">Next, we see the </span><span class="cls_007">Grid_MouseMove</span><span class="cls_004"> event handling method that was attached to the </span><span class="cls_007">rootGrid</span></div>
<div style="position:absolute;left:5.00px;top:381.75px" class="cls_004"><span class="cls_004">variable in the </span><span class="cls_007">OnApplyTemplate</span><span class="cls_004"> method. In it, we check that the mouse is currently over the</span></div>
<div style="position:absolute;left:5.00px;top:399.75px" class="cls_004"><span class="cls_004">grid and that the </span><span class="cls_007">glowBrush</span><span class="cls_004"> variable is not null. If these conditions are true, we call the</span></div>
<div style="position:absolute;left:5.00px;top:417.75px" class="cls_007"><span class="cls_007">GetPosition</span><span class="cls_004"> method on the </span><span class="cls_007">MouseEventArgs</span><span class="cls_004"> input parameter to get the current position of</span></div>
<div style="position:absolute;left:5.00px;top:435.75px" class="cls_004"><span class="cls_004">the mouse.</span></div>
<div style="position:absolute;left:5.00px;top:453.75px" class="cls_004"><span class="cls_004">Using the mouse position and the current value of the </span><span class="cls_007">GlowMode</span><span class="cls_004"> property, we determine the</span></div>
<div style="position:absolute;left:5.00px;top:471.75px" class="cls_004"><span class="cls_004">movement mode and update the position of the </span><span class="cls_007">glowBrush</span><span class="cls_004"> field's </span><span class="cls_007">Center</span><span class="cls_004"> and/or</span></div>
<div style="position:absolute;left:5.00px;top:489.75px" class="cls_007"><span class="cls_007">GradientOrigin</span><span class="cls_004"> properties. This has the effect of moving the center and/or the focal point</span></div>
<div style="position:absolute;left:5.00px;top:507.75px" class="cls_004"><span class="cls_004">of the gradient with the mouse cursor when it is over our glow button. Let's see the XAML in</span></div>
<div style="position:absolute;left:5.00px;top:525.75px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">Generic.xaml</span><span class="cls_004"> file now:</span></div>
<div style="position:absolute;left:52.98px;top:549.00px" class="cls_007"><span class="cls_007"><Style TargetType="{x:Type CustomControls:GlowButton}"></span></div>
<div style="position:absolute;left:67.97px;top:562.50px" class="cls_007"><span class="cls_007"><Setter Property="Template"></span></div>
<div style="position:absolute;left:82.97px;top:576.00px" class="cls_007"><span class="cls_007"><Setter.Value></span></div>
<div style="position:absolute;left:97.96px;top:589.50px" class="cls_007"><span class="cls_007"><ControlTemplate TargetType="{x:Type</span></div>
<div style="position:absolute;left:52.98px;top:603.00px" class="cls_007"><span class="cls_007">CustomControls:GlowButton}"></span></div>
<div style="position:absolute;left:112.96px;top:616.50px" class="cls_007"><span class="cls_007"><Grid Name="PART_Root"></span></div>
<div style="position:absolute;left:127.95px;top:630.00px" class="cls_007"><span class="cls_007"><Grid.Resources></span></div>
<div style="position:absolute;left:142.94px;top:643.50px" class="cls_007"><span class="cls_007"><RadialGradientBrush x:Key="GlowBrush"</span></div>
<div style="position:absolute;left:157.94px;top:657.00px" class="cls_007"><span class="cls_007">RadiusY="0.622" Center="0.5,0.848"</span></div>
<div style="position:absolute;left:157.94px;top:670.50px" class="cls_007"><span class="cls_007">GradientOrigin="0.5,0.818" RadiusX="1.5"></span></div>
<div style="position:absolute;left:157.94px;top:684.00px" class="cls_007"><span class="cls_007"><RadialGradientBrush.RelativeTransform></span></div>
<div style="position:absolute;left:172.93px;top:697.50px" class="cls_007"><span class="cls_007"><ScaleTransform x:Name="ScaleTransform"</span></div>
<div style="position:absolute;left:187.92px;top:711.00px" class="cls_007"><span class="cls_007">CenterX="0.5" CenterY="0.5" ScaleX="1.0"</span></div>
<div style="position:absolute;left:52.98px;top:724.50px" class="cls_007"><span class="cls_007">ScaleY="1.8" /></span></div>
<div style="position:absolute;left:157.94px;top:738.00px" class="cls_007"><span class="cls_007"></RadialGradientBrush.RelativeTransform></span></div>
<div style="position:absolute;left:157.94px;top:751.50px" class="cls_007"><span class="cls_007"><GradientStop Color="#B9F6F2FF" /></span></div>
<div style="position:absolute;left:157.94px;top:765.00px" class="cls_007"><span class="cls_007"><GradientStop Color="#A9F4EFFF" Offset="0.099" /></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:249422px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background313.jpg" width=612 height=792></div>
<div style="position:absolute;left:157.94px;top:3.00px" class="cls_007"><span class="cls_007"><GradientStop Color="{Binding GlowColor}"</span></div>
<div style="position:absolute;left:52.98px;top:16.50px" class="cls_007"><span class="cls_007">Offset="0.608" /></span></div>
<div style="position:absolute;left:157.94px;top:30.00px" class="cls_007"><span class="cls_007"><GradientStop Offset="1" Color="#004700FF" /></span></div>
<div style="position:absolute;left:142.94px;top:43.50px" class="cls_007"><span class="cls_007"></RadialGradientBrush></span></div>
<div style="position:absolute;left:142.94px;top:57.00px" class="cls_007"><span class="cls_007"><RadialGradientBrush</span></div>
<div style="position:absolute;left:52.98px;top:70.50px" class="cls_007"><span class="cls_007">x:Key="LayeredButtonBackgroundBrush"</span></div>
<div style="position:absolute;left:157.94px;top:84.00px" class="cls_007"><span class="cls_007">RadiusX="1.85" RadiusY="0.796" Center="1.018, -0.115"</span></div>
<div style="position:absolute;left:157.94px;top:97.50px" class="cls_007"><span class="cls_007">GradientOrigin="0.65,-0.139"></span></div>
<div style="position:absolute;left:157.94px;top:111.00px" class="cls_007"><span class="cls_007"><GradientStop Color="#FFCACACD" /></span></div>
<div style="position:absolute;left:157.94px;top:124.50px" class="cls_007"><span class="cls_007"><GradientStop Color="#FF3B3D42" Offset="1" /></span></div>
<div style="position:absolute;left:142.94px;top:138.00px" class="cls_007"><span class="cls_007"></RadialGradientBrush></span></div>
<div style="position:absolute;left:142.94px;top:151.50px" class="cls_007"><span class="cls_007"><LinearGradientBrush x:Key="LayeredButtonCurveBrush"</span></div>
<div style="position:absolute;left:157.94px;top:165.00px" class="cls_007"><span class="cls_007">StartPoint="0,0" EndPoint="1,1"></span></div>
<div style="position:absolute;left:157.94px;top:178.50px" class="cls_007"><span class="cls_007"><GradientStop Color="#FF747475" Offset="0" /></span></div>
<div style="position:absolute;left:157.94px;top:192.00px" class="cls_007"><span class="cls_007"><GradientStop Color="#FF3B3D42" Offset="1" /></span></div>
<div style="position:absolute;left:142.94px;top:205.50px" class="cls_007"><span class="cls_007"></LinearGradientBrush></span></div>
<div style="position:absolute;left:142.94px;top:219.00px" class="cls_007"><span class="cls_007"><Grid x:Key="LayeredButtonBackgroundElements"></span></div>
<div style="position:absolute;left:157.94px;top:232.50px" class="cls_007"><span class="cls_007"><Rectangle</span></div>
<div style="position:absolute;left:172.93px;top:246.00px" class="cls_007"><span class="cls_007">Fill="{StaticResource</span></div>
<div style="position:absolute;left:52.98px;top:259.50px" class="cls_007"><span class="cls_007">LayeredButtonBackgroundBrush}" /></span></div>
<div style="position:absolute;left:157.94px;top:273.00px" class="cls_007"><span class="cls_007"><Path StrokeThickness="0"</span></div>
<div style="position:absolute;left:172.93px;top:286.50px" class="cls_007"><span class="cls_007">Fill="{StaticResource LayeredButtonCurveBrush}"></span></div>
<div style="position:absolute;left:172.93px;top:300.00px" class="cls_007"><span class="cls_007"><Path.Data></span></div>
<div style="position:absolute;left:187.92px;top:313.50px" class="cls_007"><span class="cls_007"><CombinedGeometry</span></div>
<div style="position:absolute;left:52.98px;top:327.00px" class="cls_007"><span class="cls_007">GeometryCombineMode="Intersect"></span></div>
<div style="position:absolute;left:202.92px;top:340.50px" class="cls_007"><span class="cls_007"><CombinedGeometry.Geometry1></span></div>
<div style="position:absolute;left:217.91px;top:354.00px" class="cls_007"><span class="cls_007"><EllipseGeometry Center="-20,50.7"</span></div>
<div style="position:absolute;left:52.98px;top:367.50px" class="cls_007"><span class="cls_007">RadiusX="185"</span></div>
<div style="position:absolute;left:232.91px;top:381.00px" class="cls_007"><span class="cls_007">RadiusY="46" /></span></div>
<div style="position:absolute;left:202.92px;top:394.50px" class="cls_007"><span class="cls_007"></CombinedGeometry.Geometry1></span></div>
<div style="position:absolute;left:202.92px;top:408.00px" class="cls_007"><span class="cls_007"><CombinedGeometry.Geometry2></span></div>
<div style="position:absolute;left:217.91px;top:421.50px" class="cls_007"><span class="cls_007"><RectangleGeometry Rect="0,0,106,24" /></span></div>
<div style="position:absolute;left:202.92px;top:435.00px" class="cls_007"><span class="cls_007"></CombinedGeometry.Geometry2></span></div>
<div style="position:absolute;left:187.92px;top:448.50px" class="cls_007"><span class="cls_007"></CombinedGeometry></span></div>
<div style="position:absolute;left:172.93px;top:462.00px" class="cls_007"><span class="cls_007"></Path.Data></span></div>
<div style="position:absolute;left:157.94px;top:475.50px" class="cls_007"><span class="cls_007"></Path></span></div>
<div style="position:absolute;left:142.94px;top:489.00px" class="cls_007"><span class="cls_007"></Grid></span></div>
<div style="position:absolute;left:142.94px;top:502.50px" class="cls_007"><span class="cls_007"><VisualBrush x:Key="LayeredButtonBackground"</span></div>
<div style="position:absolute;left:157.94px;top:516.00px" class="cls_007"><span class="cls_007">Visual="{StaticResource</span></div>
<div style="position:absolute;left:52.98px;top:529.50px" class="cls_007"><span class="cls_007">LayeredButtonBackgroundElements}" /></span></div>
<div style="position:absolute;left:127.95px;top:543.00px" class="cls_007"><span class="cls_007"></Grid.Resources></span></div>
<div style="position:absolute;left:127.95px;top:556.50px" class="cls_007"><span class="cls_007"><Border CornerRadius="3" BorderBrush="#7F000000"</span></div>
<div style="position:absolute;left:142.94px;top:570.00px" class="cls_007"><span class="cls_007">BorderThickness="1" Background="#7FFFFFFF"</span></div>
<div style="position:absolute;left:142.94px;top:583.50px" class="cls_007"><span class="cls_007">SnapsToDevicePixels="True"></span></div>
<div style="position:absolute;left:142.94px;top:597.00px" class="cls_007"><span class="cls_007"><Border CornerRadius="2" Margin="1"</span></div>
<div style="position:absolute;left:157.94px;top:610.50px" class="cls_007"><span class="cls_007">Background="{StaticResource LayeredButtonBackground}"</span></div>
<div style="position:absolute;left:157.94px;top:624.00px" class="cls_007"><span class="cls_007">SnapsToDevicePixels="True"></span></div>
<div style="position:absolute;left:157.94px;top:637.50px" class="cls_007"><span class="cls_007"><Grid></span></div>
<div style="position:absolute;left:172.93px;top:651.00px" class="cls_007"><span class="cls_007"><Rectangle x:Name="Glow" IsHitTestVisible="False"</span></div>
<div style="position:absolute;left:187.92px;top:664.50px" class="cls_007"><span class="cls_007">RadiusX="2" RadiusY="2"</span></div>
<div style="position:absolute;left:187.92px;top:678.00px" class="cls_007"><span class="cls_007">Fill="{StaticResource GlowBrush}" Opacity="0" /></span></div>
<div style="position:absolute;left:172.93px;top:691.50px" class="cls_007"><span class="cls_007"><ContentPresenter Content="{TemplateBinding</span></div>
<div style="position:absolute;left:52.98px;top:705.00px" class="cls_007"><span class="cls_007">Content}"</span></div>
<div style="position:absolute;left:187.92px;top:718.50px" class="cls_007"><span class="cls_007">Margin="{TemplateBinding Padding}"</span></div>
<div style="position:absolute;left:187.92px;top:732.00px" class="cls_007"><span class="cls_007">HorizontalAlignment="Center"</span></div>
<div style="position:absolute;left:187.92px;top:745.50px" class="cls_007"><span class="cls_007">VerticalAlignment="Center" /></span></div>
<div style="position:absolute;left:157.94px;top:759.00px" class="cls_007"><span class="cls_007"></Grid></span></div>
<div style="position:absolute;left:142.94px;top:772.50px" class="cls_007"><span class="cls_007"></Border></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:250224px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background314.jpg" width=612 height=792></div>
<div style="position:absolute;left:127.95px;top:3.00px" class="cls_007"><span class="cls_007"></Border></span></div>
<div style="position:absolute;left:127.95px;top:16.50px" class="cls_007"><span class="cls_007"><Grid.Triggers></span></div>
<div style="position:absolute;left:142.94px;top:30.00px" class="cls_007"><span class="cls_007"><EventTrigger RoutedEvent="MouseEnter"></span></div>
<div style="position:absolute;left:157.94px;top:43.50px" class="cls_007"><span class="cls_007"><BeginStoryboard></span></div>
<div style="position:absolute;left:172.93px;top:57.00px" class="cls_007"><span class="cls_007"><Storyboard></span></div>
<div style="position:absolute;left:187.92px;top:70.50px" class="cls_007"><span class="cls_007"><DoubleAnimation Storyboard.TargetName="Glow"</span></div>
<div style="position:absolute;left:202.92px;top:84.00px" class="cls_007"><span class="cls_007">Storyboard.TargetProperty="Opacity" To="1.0"</span></div>
<div style="position:absolute;left:202.92px;top:97.50px" class="cls_007"><span class="cls_007">Duration="0:0:0.5" DecelerationRatio="1" /></span></div>
<div style="position:absolute;left:172.93px;top:111.00px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:157.94px;top:124.50px" class="cls_007"><span class="cls_007"></BeginStoryboard></span></div>
<div style="position:absolute;left:142.94px;top:138.00px" class="cls_007"><span class="cls_007"></EventTrigger></span></div>
<div style="position:absolute;left:142.94px;top:151.50px" class="cls_007"><span class="cls_007"><EventTrigger RoutedEvent="MouseLeave"></span></div>
<div style="position:absolute;left:157.94px;top:165.00px" class="cls_007"><span class="cls_007"><BeginStoryboard></span></div>
<div style="position:absolute;left:172.93px;top:178.50px" class="cls_007"><span class="cls_007"><Storyboard></span></div>
<div style="position:absolute;left:187.92px;top:192.00px" class="cls_007"><span class="cls_007"><DoubleAnimation Storyboard.TargetName="Glow"</span></div>
<div style="position:absolute;left:202.92px;top:205.50px" class="cls_007"><span class="cls_007">Storyboard.TargetProperty="Opacity" To="0.0"</span></div>
<div style="position:absolute;left:202.92px;top:219.00px" class="cls_007"><span class="cls_007">Duration="0:0:1" DecelerationRatio="1" /></span></div>
<div style="position:absolute;left:172.93px;top:232.50px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:157.94px;top:246.00px" class="cls_007"><span class="cls_007"></BeginStoryboard></span></div>
<div style="position:absolute;left:142.94px;top:259.50px" class="cls_007"><span class="cls_007"></EventTrigger></span></div>
<div style="position:absolute;left:142.94px;top:273.00px" class="cls_007"><span class="cls_007"><EventTrigger RoutedEvent="MouseDown"></span></div>
<div style="position:absolute;left:157.94px;top:286.50px" class="cls_007"><span class="cls_007"><BeginStoryboard></span></div>
<div style="position:absolute;left:172.93px;top:300.00px" class="cls_007"><span class="cls_007"><Storyboard></span></div>
<div style="position:absolute;left:187.92px;top:313.50px" class="cls_007"><span class="cls_007"><DoubleAnimation</span></div>
<div style="position:absolute;left:52.98px;top:327.00px" class="cls_007"><span class="cls_007">Storyboard.TargetName="ScaleTransform"</span></div>
<div style="position:absolute;left:202.92px;top:340.50px" class="cls_007"><span class="cls_007">Storyboard.TargetProperty="ScaleX" From="10.0"</span></div>
<div style="position:absolute;left:202.92px;top:354.00px" class="cls_007"><span class="cls_007">To="1.0" Duration="0:0:0.15"</span></div>
<div style="position:absolute;left:52.98px;top:367.50px" class="cls_007"><span class="cls_007">AccelerationRatio="0.5" /></span></div>
<div style="position:absolute;left:187.92px;top:381.00px" class="cls_007"><span class="cls_007"><DoubleAnimation</span></div>
<div style="position:absolute;left:52.98px;top:394.50px" class="cls_007"><span class="cls_007">Storyboard.TargetName="ScaleTransform"</span></div>
<div style="position:absolute;left:202.92px;top:408.00px" class="cls_007"><span class="cls_007">Storyboard.TargetProperty="ScaleY" From="10.0"</span></div>
<div style="position:absolute;left:202.92px;top:421.50px" class="cls_007"><span class="cls_007">To="1.8" Duration="0:0:0.15"</span></div>
<div style="position:absolute;left:52.98px;top:435.00px" class="cls_007"><span class="cls_007">AccelerationRatio="0.5" /></span></div>
<div style="position:absolute;left:172.93px;top:448.50px" class="cls_007"><span class="cls_007"></Storyboard></span></div>
<div style="position:absolute;left:157.94px;top:462.00px" class="cls_007"><span class="cls_007"></BeginStoryboard></span></div>
<div style="position:absolute;left:142.94px;top:475.50px" class="cls_007"><span class="cls_007"></EventTrigger></span></div>
<div style="position:absolute;left:127.95px;top:489.00px" class="cls_007"><span class="cls_007"></Grid.Triggers></span></div>
<div style="position:absolute;left:112.96px;top:502.50px" class="cls_007"><span class="cls_007"></Grid></span></div>
<div style="position:absolute;left:97.96px;top:516.00px" class="cls_007"><span class="cls_007"></ControlTemplate></span></div>
<div style="position:absolute;left:82.97px;top:529.50px" class="cls_007"><span class="cls_007"></Setter.Value></span></div>
<div style="position:absolute;left:67.97px;top:543.00px" class="cls_007"><span class="cls_007"></Setter></span></div>
<div style="position:absolute;left:52.98px;top:556.50px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:5.00px;top:589.50px" class="cls_004"><span class="cls_004">Inside this </span><span class="cls_007">ControlTemplate</span><span class="cls_004">, we see the </span><span class="cls_007">Grid</span><span class="cls_004"> named </span><span class="cls_007">PART_Root</span><span class="cls_004"> and inside it, we see some</span></div>
<div style="position:absolute;left:5.00px;top:607.50px" class="cls_004"><span class="cls_004">resources declared within its </span><span class="cls_007">Resources</span><span class="cls_004"> section. Much of this XAML is taken up by the</span></div>
<div style="position:absolute;left:5.00px;top:625.50px" class="cls_004"><span class="cls_004">same resources that we used in our layered button background example, so we can skip</span></div>
<div style="position:absolute;left:5.00px;top:643.50px" class="cls_004"><span class="cls_004">their explanation.</span></div>
<div style="position:absolute;left:5.00px;top:661.50px" class="cls_004"><span class="cls_004">There is however, one new resource of type </span><span class="cls_007">RadialGradientBrush</span><span class="cls_004"> and named </span><span class="cls_007">GlowBrush</span><span class="cls_004">.</span></div>
<div style="position:absolute;left:5.00px;top:679.50px" class="cls_004"><span class="cls_004">This is the brush that puts the color into our button. In particular, note that its</span></div>
<div style="position:absolute;left:5.00px;top:697.50px" class="cls_007"><span class="cls_007">RelativeTransform</span><span class="cls_004"> property is set to a </span><span class="cls_007">ScaleTransform</span><span class="cls_004"> element named </span><span class="cls_007">ScaleTransform</span></div>
<div style="position:absolute;left:5.00px;top:715.50px" class="cls_004"><span class="cls_004">and that its third </span><span class="cls_007">GradientStop</span><span class="cls_004"> object is data bound to the </span><span class="cls_007">GlowColor</span><span class="cls_004"> property from our</span></div>
<div style="position:absolute;left:5.00px;top:733.50px" class="cls_004"><span class="cls_004">control.</span></div>
<div style="position:absolute;left:5.00px;top:751.50px" class="cls_004"><span class="cls_004">In the actual template, we see our double </span><span class="cls_007">Border</span><span class="cls_004"> elements with their </span><span class="cls_007">SnapsToDevicePixels</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:251026px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background315.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">properties set to true to ensure a sharp rendered image. Again, the outer border has a</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">larger </span><span class="cls_007">CornerRadius</span><span class="cls_004"> value than the inner border to ensure their tight fit together and the</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">inner border's background is painted with the </span><span class="cls_007">LayeredButtonBackground</span><span class="cls_004"> visual brush.</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">Inside the inner border, we have a </span><span class="cls_007">Grid</span><span class="cls_004"> panel that contains a </span><span class="cls_007">Rectangle</span><span class="cls_004"> element and the</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">required </span><span class="cls_007">ContentPresenter</span><span class="cls_004"> object. We use the </span><span class="cls_007">GlowBrush</span><span class="cls_004"> resource to paint the background</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">of the rectangle and set its </span><span class="cls_007">IsHitTestVisible</span><span class="cls_004"> property to </span><span class="cls_007">false</span><span class="cls_004">, so that it takes no part in</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">user interaction. Note that in this example, we set its </span><span class="cls_007">Opacity</span><span class="cls_004"> property to zero to make it</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">initially invisible.</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">We data bind the button's </span><span class="cls_007">Content</span><span class="cls_004"> and </span><span class="cls_007">Padding</span><span class="cls_004"> properties to the </span><span class="cls_007">Content</span><span class="cls_004"> and </span><span class="cls_007">Margin</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">properties of the </span><span class="cls_007">ContentPresenter</span><span class="cls_004"> element respectively, and center it within the control.</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">That completes the visual markup for our glow button and now, we reach the all-important</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_007"><span class="cls_007">Grid.Triggers</span><span class="cls_004"> collection, where we declare three </span><span class="cls_007">EventTrigger</span><span class="cls_004"> objects to trigger our</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">mouse over effects.</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">The first trigger starts its associated storyboard when the </span><span class="cls_007">MouseEnter</span><span class="cls_004"> event is raised. It's</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">associated </span><span class="cls_007">DoubleAnimation</span><span class="cls_004"> object animates the 'glowing' rectangle's </span><span class="cls_007">Opacity</span><span class="cls_004"> property to</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_007"><span class="cls_007">1.0</span><span class="cls_004"> over half a second. Note that we omit the </span><span class="cls_007">From</span><span class="cls_004"> property here, so that the </span><span class="cls_007">Opacity</span><span class="cls_004"> value</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">will start animating from its current value, rather than jumping back to </span><span class="cls_007">0.0</span><span class="cls_004"> each time it starts</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">the animation.</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_004"><span class="cls_004">The second trigger starts its storyboard when the </span><span class="cls_007">MouseLeave</span><span class="cls_004"> event is raised. It's</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_007"><span class="cls_007">DoubleAnimation</span><span class="cls_004"> object animates the rectangle's </span><span class="cls_007">Opacity</span><span class="cls_004"> property back to </span><span class="cls_007">0.0</span><span class="cls_004"> over a</span></div>
<div style="position:absolute;left:5.00px;top:363.75px" class="cls_004"><span class="cls_004">whole second. Note that we also omit the </span><span class="cls_007">From</span><span class="cls_004"> property here, so that the </span><span class="cls_007">Opacity</span><span class="cls_004"> value will</span></div>
<div style="position:absolute;left:5.00px;top:381.75px" class="cls_004"><span class="cls_004">start animating from its current value, rather than jumping to </span><span class="cls_007">1.0</span><span class="cls_004"> each time it starts its</span></div>
<div style="position:absolute;left:5.00px;top:399.75px" class="cls_004"><span class="cls_004">animation. This ensures a smoother transition.</span></div>
<div style="position:absolute;left:5.00px;top:417.75px" class="cls_004"><span class="cls_004">The third trigger starts its storyboard when the </span><span class="cls_007">MouseDown</span><span class="cls_004"> event is raised and it contains</span></div>
<div style="position:absolute;left:5.00px;top:435.75px" class="cls_004"><span class="cls_004">two </span><span class="cls_007">DoubleAnimation</span><span class="cls_004"> objects. They animate the </span><span class="cls_007">ScaleX</span><span class="cls_004"> and </span><span class="cls_007">ScaleY</span><span class="cls_004"> properties of the</span></div>
<div style="position:absolute;left:5.00px;top:453.75px" class="cls_007"><span class="cls_007">ScaleTransform</span><span class="cls_004"> object from </span><span class="cls_007">10.0</span><span class="cls_004"> to their usual values over one hundred and fifty</span></div>
<div style="position:absolute;left:5.00px;top:471.75px" class="cls_004"><span class="cls_004">milliseconds, which produces an interesting effect when the user clicks the button.</span></div>
<div style="position:absolute;left:5.00px;top:489.75px" class="cls_004"><span class="cls_004">Using the </span><span class="cls_007">GlowColor</span><span class="cls_004"> and </span><span class="cls_007">GlowMode</span><span class="cls_004"> properties, we can produce a wide range of buttons and</span></div>
<div style="position:absolute;left:5.00px;top:507.75px" class="cls_004"><span class="cls_004">interaction effects. After defining the relevant XAML namespace in our View, we can use</span></div>
<div style="position:absolute;left:5.00px;top:525.75px" class="cls_004"><span class="cls_004">this glow button example in the following way:</span></div>
<div style="position:absolute;left:52.98px;top:549.00px" class="cls_007"><span class="cls_007"><CustomControls:GlowButton Content="Glowing button"</span></div>
<div style="position:absolute;left:67.97px;top:562.50px" class="cls_007"><span class="cls_007">GlowMode="NoCenterMovement" GlowColor="Red" FontSize="28"</span></div>
<div style="position:absolute;left:67.97px;top:576.00px" class="cls_007"><span class="cls_007">Foreground="White" Height="60" Width="275" /></span></div>
<div style="position:absolute;left:5.00px;top:596.25px" class="cls_004"><span class="cls_004">When our example is run, it can produce mouse over effects, which vary depending on the</span></div>
<div style="position:absolute;left:5.00px;top:614.25px" class="cls_004"><span class="cls_004">position of the mouse cursor, as shown in the following examples:</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:251828px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background316.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:159.00px" class="cls_004"><span class="cls_004">The top left image illustrates the </span><span class="cls_007">HorizontalCenterMovement</span><span class="cls_004"> mode, the top right shows the</span></div>
<div style="position:absolute;left:5.00px;top:177.00px" class="cls_007"><span class="cls_007">FullCenterMovement</span><span class="cls_004"> mode and the bottom two highlight two mouse positions when using</span></div>
<div style="position:absolute;left:5.00px;top:195.00px" class="cls_004"><span class="cls_004">the </span><span class="cls_007">NoCenterMovement</span><span class="cls_004"> mode. The top two use the default color and the bottom two were</span></div>
<div style="position:absolute;left:5.00px;top:213.00px" class="cls_004"><span class="cls_004">rendered using a </span><span class="cls_007">GlowColor</span><span class="cls_004"> of </span><span class="cls_007">Red</span><span class="cls_004">. This reveals the differences between the various </span><span class="cls_007">Glow</span></div>
<div style="position:absolute;left:5.00px;top:231.00px" class="cls_007"><span class="cls_007">Mode</span><span class="cls_004"> values in our example.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:252630px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background317.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_008"><span class="cls_008">Summary</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">In this chapter, we investigated a number of techniques that we can use to improve the look</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">of our applications, from simply adding shadows to implementing far more complicated</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">layered visuals. We saw the importance of remaining consistent throughout our application</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">and how to get that professional look.</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">We then looked at more advanced techniques for making our application stand out from the</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">crowd and saw further examples of how to create a variety of custom controls. We finished</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">with a look at how we can incorporate animations into our everyday controls, in order to</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">bring about a sense of exclusivity to our applications.</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">In the following chapter, we're going to investigate a number of ways that we can validate</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">the data in our applications. We'll examine the various validation interfaces that are available</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">to us in WPF and work on extending our application framework with a complete validation</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">system using data annotations.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:253432px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background318.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_002"><span class="cls_002">Chapter 8. Implementing Responsive Data</span></div>
<div style="position:absolute;left:5.00px;top:39.01px" class="cls_002"><span class="cls_002">Validation</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">Data validation goes hand in hand with data input forms and is essential to promote clean,</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">usable data. While the UI controls in WPF can automatically validate that entered values</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">match the type of their data bound properties, they cannot validate for the correctness of</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">the entered data.</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">For example, a </span><span class="cls_007">TextBox</span><span class="cls_004"> control that is data bound to an integer may highlight an error if a</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">user entered a non-numeric value, but it wouldn't validate that the entered number had the</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">correct number of digits in, or that the first four digits were appropriate for the type of credit</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">card specified.</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">In order to validate these types of data correctness when using MVVM, we'll need to</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">implement one of the .NET validation interfaces. In this chapter, we'll thoroughly examine</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">the available interfaces, looking at a number of implementations and explore the other</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">validation related features that WPF provides us with. Let's start by looking at the validation</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">system.</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">In WPF, the validation system very much revolves around the static </span><span class="cls_007">Validation</span><span class="cls_004"> class. This</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_004"><span class="cls_004">class has several Attached Properties, methods and an Attached Event that support data</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_004"><span class="cls_004">validation. Each binding instance has a </span><span class="cls_007">ValidationRules</span><span class="cls_004"> collection that can contain</span></div>
<div style="position:absolute;left:5.00px;top:363.75px" class="cls_007"><span class="cls_007">ValidationRule</span><span class="cls_004"> elements.</span></div>
<div style="position:absolute;left:5.00px;top:381.75px" class="cls_004"><span class="cls_004">WPF provides three built-in rules; the </span><span class="cls_007">ExceptionValidationRule</span><span class="cls_004"> object checks for any</span></div>
<div style="position:absolute;left:5.00px;top:399.75px" class="cls_004"><span class="cls_004">exceptions thrown as the binding source property is updated, the </span><span class="cls_007">DataErrorValidationRule</span></div>
<div style="position:absolute;left:5.00px;top:417.75px" class="cls_004"><span class="cls_004">class checks for errors that may be raised by classes that implement the </span><span class="cls_007">IDataErrorInfo</span></div>
<div style="position:absolute;left:5.00px;top:435.75px" class="cls_004"><span class="cls_004">interface and the </span><span class="cls_007">NotifyDataErrorValidationRule</span><span class="cls_004"> class checks for errors raised by</span></div>
<div style="position:absolute;left:5.00px;top:453.75px" class="cls_004"><span class="cls_004">classes that implement the</span><span class="cls_007"> INotifyDataErrorInfo</span><span class="cls_004"> interface.</span></div>
<div style="position:absolute;left:5.00px;top:471.75px" class="cls_004"><span class="cls_004">Each time an attempt is made to update a data source property, the binding engine first</span></div>
<div style="position:absolute;left:5.00px;top:489.75px" class="cls_004"><span class="cls_004">clears the </span><span class="cls_007">Validation.Errors</span><span class="cls_004"> collection and then checks the binding's </span><span class="cls_007">ValidationRules</span></div>
<div style="position:absolute;left:5.00px;top:507.75px" class="cls_004"><span class="cls_004">collection to see if it contains any </span><span class="cls_007">ValidationRule</span><span class="cls_004"> elements. If it does, it calls each rule's</span></div>
<div style="position:absolute;left:5.00px;top:525.75px" class="cls_007"><span class="cls_007">Validate</span><span class="cls_004"> method in turn until they all pass, or one returns an error.</span></div>
<div style="position:absolute;left:5.00px;top:543.75px" class="cls_004"><span class="cls_004">When a data bound value fails the condition in the </span><span class="cls_007">Validation</span><span class="cls_004"> method of a </span><span class="cls_007">ValidationRule</span></div>
<div style="position:absolute;left:5.00px;top:561.75px" class="cls_004"><span class="cls_004">element, the binding engine adds a new </span><span class="cls_007">ValidationError</span><span class="cls_004"> object to the </span><span class="cls_007">Validation.Errors</span></div>
<div style="position:absolute;left:5.00px;top:579.75px" class="cls_004"><span class="cls_004">collection of the data binding target control.</span></div>
<div style="position:absolute;left:5.00px;top:597.75px" class="cls_004"><span class="cls_004">This in turn, will set the </span><span class="cls_007">Validation.HasError</span><span class="cls_004"> Attached Property of the element to </span><span class="cls_007">true</span><span class="cls_004"> and</span></div>
<div style="position:absolute;left:5.00px;top:615.75px" class="cls_004"><span class="cls_004">if the </span><span class="cls_007">NotifyOnValidationError</span><span class="cls_004"> property of the binding is set to </span><span class="cls_007">true</span><span class="cls_004">, the binding engine</span></div>
<div style="position:absolute;left:5.00px;top:633.75px" class="cls_004"><span class="cls_004">will also raise the </span><span class="cls_007">Validation.Error</span><span class="cls_004"> Attached Event on the data binding target.</span></div>
<div style="position:absolute;left:5.00px;top:651.01px" class="cls_008"><span class="cls_008">Using validation rules - To do or not to do?</span></div>
<div style="position:absolute;left:5.00px;top:687.75px" class="cls_004"><span class="cls_004">In WPF, there are two different approaches for dealing with data validation. On the one</span></div>
<div style="position:absolute;left:5.00px;top:705.75px" class="cls_004"><span class="cls_004">hand, we have the UI-based </span><span class="cls_007">ValidationRule</span><span class="cls_004"> classes, the </span><span class="cls_007">Validation.Error</span><span class="cls_004"> Attached</span></div>
<div style="position:absolute;left:5.00px;top:723.75px" class="cls_004"><span class="cls_004">Event and the </span><span class="cls_007">Binding.NotifyOnValidationError</span><span class="cls_004"> and </span><span class="cls_007">UpdateSourceExceptionFilter</span></div>
<div style="position:absolute;left:5.00px;top:741.75px" class="cls_004"><span class="cls_004">properties and on the other, we have two code-based validation interfaces.</span></div>
<div style="position:absolute;left:5.00px;top:759.75px" class="cls_004"><span class="cls_004">While the </span><span class="cls_007">ValidationRule</span><span class="cls_004"> classes and their related validation approach work perfectly well,</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:254234px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background319.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">they are specified in the XAML and as such, are tied to the UI. Furthermore, when using the</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_007"><span class="cls_007">ValidationRule</span><span class="cls_004"> classes, we are effectively separating the validation logic from the data</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">models that they are validating and storing it in a completely different assembly.</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">When developing a WPF application using the MVVM methodology, we work with data,</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">rather than UI elements and so, we tend to shy away from using the </span><span class="cls_007">ValidationRule</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">classes and their related validation strategy directly.</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">Additionally, the </span><span class="cls_007">NotifyOnValidationError</span><span class="cls_004"> and </span><span class="cls_007">UpdateSourceExceptionFilter</span><span class="cls_004"> properties</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">of the </span><span class="cls_007">Binding</span><span class="cls_004"> class also require event or delegate handlers respectively and as we have</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">discovered, we prefer to avoid doing this when using MVVM. Therefore, we will not be</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">looking at this UI-based validation approach in this book, instead focusing on the two code-</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">based validation interfaces.</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:255036px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background320.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.01px" class="cls_008"><span class="cls_008">Getting to grips with validation interfaces</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">In WPF, we have access to two main validation interfaces; the original one is the</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_007"><span class="cls_007">IDataErrorInfo</span><span class="cls_004"> interface and in .NET 4.5, the </span><span class="cls_007">INotifyDataErrorInfo</span><span class="cls_004"> interface was added.</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">In this section, we'll first investigate the original validation interface and its shortcomings and</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">see how we can make it more usable, before examining the latter.</span></div>
<div style="position:absolute;left:5.00px;top:111.01px" class="cls_011"><span class="cls_011">Implementing the IDataErrorInfo interface</span></div>
<div style="position:absolute;left:5.00px;top:141.00px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">IDataErrorInfo</span><span class="cls_004"> interface is a very simple affair, with only two required properties to</span></div>
<div style="position:absolute;left:5.00px;top:159.00px" class="cls_004"><span class="cls_004">implement. The </span><span class="cls_007">Error</span><span class="cls_004"> property returns the error message that describes the validation</span></div>
<div style="position:absolute;left:5.00px;top:177.00px" class="cls_004"><span class="cls_004">error and the </span><span class="cls_007">Item[string]</span><span class="cls_004"> indexer returns the error message for the specified property.</span></div>
<div style="position:absolute;left:5.00px;top:195.00px" class="cls_004"><span class="cls_004">It certainly seems straight forward enough, so let's take a look at a basic implementation of</span></div>
<div style="position:absolute;left:5.00px;top:213.00px" class="cls_004"><span class="cls_004">this interface. Let's create another base class to implement this in and for now, omit all</span></div>
<div style="position:absolute;left:5.00px;top:231.00px" class="cls_004"><span class="cls_004">other unrelated base class members, so that we can concentrate on this interface.</span></div>
<div style="position:absolute;left:52.98px;top:254.25px" class="cls_007"><span class="cls_007">using System.ComponentModel;</span></div>
<div style="position:absolute;left:52.98px;top:267.75px" class="cls_007"><span class="cls_007">using System.Runtime.CompilerServices;</span></div>
<div style="position:absolute;left:52.98px;top:294.75px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.DataModels</span></div>
<div style="position:absolute;left:52.98px;top:308.25px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:321.75px" class="cls_007"><span class="cls_007">public abstract class BaseValidationModel :</span></div>
<div style="position:absolute;left:52.98px;top:335.25px" class="cls_007"><span class="cls_007">INotifyPropertyChanged,</span></div>
<div style="position:absolute;left:82.97px;top:348.75px" class="cls_007"><span class="cls_007">IDataErrorInfo</span></div>
<div style="position:absolute;left:67.97px;top:362.25px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:375.75px" class="cls_007"><span class="cls_007">protected string error = string.Empty;</span></div>
<div style="position:absolute;left:82.97px;top:402.75px" class="cls_007"><span class="cls_007">#region IDataErrorInfo Members</span></div>
<div style="position:absolute;left:82.97px;top:429.75px" class="cls_007"><span class="cls_007">public string Error => error;</span></div>
<div style="position:absolute;left:82.97px;top:456.75px" class="cls_007"><span class="cls_007">public virtual string this[string propertyName] => error;</span></div>
<div style="position:absolute;left:82.97px;top:483.75px" class="cls_007"><span class="cls_007">#endregion</span></div>
<div style="position:absolute;left:82.97px;top:510.75px" class="cls_007"><span class="cls_007">#region INotifyPropertyChanged Members</span></div>
<div style="position:absolute;left:82.97px;top:564.75px" class="cls_007"><span class="cls_007">#endregion</span></div>
<div style="position:absolute;left:67.97px;top:578.25px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:591.75px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:612.00px" class="cls_004"><span class="cls_004">In this simplest of implementations, we have declared a protected </span><span class="cls_007">error</span><span class="cls_004"> field, that will be</span></div>
<div style="position:absolute;left:5.00px;top:630.00px" class="cls_004"><span class="cls_004">accessible to derived classes. Note that the </span><span class="cls_007">Error</span><span class="cls_004"> property that returns it uses the C# 6.0</span></div>
<div style="position:absolute;left:5.00px;top:648.00px" class="cls_004"><span class="cls_004">expression bodied property syntax. This new syntax is nothing but a shorthand notation for</span></div>
<div style="position:absolute;left:5.00px;top:666.00px" class="cls_004"><span class="cls_004">simple methods or getter only properties that return something, where the member body is</span></div>
<div style="position:absolute;left:5.00px;top:684.00px" class="cls_004"><span class="cls_004">replaced with an inline expression.</span></div>
<div style="position:absolute;left:5.00px;top:702.00px" class="cls_004"><span class="cls_004">We have declared the class indexer (the </span><span class="cls_007">this</span><span class="cls_004"> property) as </span><span class="cls_007">virtual</span><span class="cls_004">, so that we can</span></div>
<div style="position:absolute;left:5.00px;top:720.00px" class="cls_004"><span class="cls_004">override it in the derived classes. Another option would be to declare it as </span><span class="cls_007">abstract</span><span class="cls_004">, so that</span></div>
<div style="position:absolute;left:5.00px;top:738.00px" class="cls_004"><span class="cls_004">derived classes were forced to override it. Whether you prefer to use </span><span class="cls_007">virtual</span><span class="cls_004"> or </span><span class="cls_007">abstract</span></div>
<div style="position:absolute;left:5.00px;top:756.00px" class="cls_004"><span class="cls_004">will depend on your particular circumstances, such as whether you expect every derived</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:255838px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background321.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">class to need validation or not.</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">Let's take a look at an example of a class that derives from our new base class:</span></div>
<div style="position:absolute;left:52.98px;top:45.00px" class="cls_007"><span class="cls_007">using System;</span></div>
<div style="position:absolute;left:52.98px;top:72.00px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.DataModels</span></div>
<div style="position:absolute;left:52.98px;top:85.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:99.00px" class="cls_007"><span class="cls_007">public class Product : BaseValidationModel</span></div>
<div style="position:absolute;left:67.97px;top:112.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:126.00px" class="cls_007"><span class="cls_007">private Guid id = Guid.Empty;</span></div>
<div style="position:absolute;left:82.97px;top:139.50px" class="cls_007"><span class="cls_007">private string name = string.Empty;</span></div>
<div style="position:absolute;left:82.97px;top:153.00px" class="cls_007"><span class="cls_007">private decimal price = 0;</span></div>
<div style="position:absolute;left:82.97px;top:180.00px" class="cls_007"><span class="cls_007">public Guid Id</span></div>
<div style="position:absolute;left:82.97px;top:193.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:207.00px" class="cls_007"><span class="cls_007">get { return id; }</span></div>
<div style="position:absolute;left:97.96px;top:220.50px" class="cls_007"><span class="cls_007">set { if (id != value) { id = value; NotifyPropertyChanged();</span></div>
<div style="position:absolute;left:52.98px;top:234.00px" class="cls_007"><span class="cls_007">} }</span></div>
<div style="position:absolute;left:82.97px;top:247.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:274.50px" class="cls_007"><span class="cls_007">public string Name</span></div>
<div style="position:absolute;left:82.97px;top:288.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:301.50px" class="cls_007"><span class="cls_007">get { return name; }</span></div>
<div style="position:absolute;left:97.96px;top:315.00px" class="cls_007"><span class="cls_007">set { if (name != value) { name = value;</span></div>
<div style="position:absolute;left:52.98px;top:328.50px" class="cls_007"><span class="cls_007">NotifyPropertyChanged(); } }</span></div>
<div style="position:absolute;left:82.97px;top:342.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:369.00px" class="cls_007"><span class="cls_007">public decimal Price</span></div>
<div style="position:absolute;left:82.97px;top:382.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:396.00px" class="cls_007"><span class="cls_007">get { return price; }</span></div>
<div style="position:absolute;left:97.96px;top:409.50px" class="cls_007"><span class="cls_007">set { if (price != value) { price = value;</span></div>
<div style="position:absolute;left:112.96px;top:423.00px" class="cls_007"><span class="cls_007">NotifyPropertyChanged(); } }</span></div>
<div style="position:absolute;left:82.97px;top:436.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:463.50px" class="cls_007"><span class="cls_007">public override string this[string propertyName]</span></div>
<div style="position:absolute;left:82.97px;top:477.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:490.50px" class="cls_007"><span class="cls_007">get</span></div>
<div style="position:absolute;left:97.96px;top:504.00px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:112.96px;top:517.50px" class="cls_007"><span class="cls_007">error = string.Empty;</span></div>
<div style="position:absolute;left:112.96px;top:531.00px" class="cls_007"><span class="cls_007">if (propertyName == nameof(Name))</span></div>
<div style="position:absolute;left:112.96px;top:544.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:127.95px;top:558.00px" class="cls_007"><span class="cls_007">if (string.IsNullOrEmpty(Name))</span></div>
<div style="position:absolute;left:142.94px;top:571.50px" class="cls_007"><span class="cls_007">error = "Please enter the product name.";</span></div>
<div style="position:absolute;left:127.95px;top:585.00px" class="cls_007"><span class="cls_007">else if (Name.Length > 25) error = "The product name</span></div>
<div style="position:absolute;left:52.98px;top:598.50px" class="cls_007"><span class="cls_007">cannot be</span></div>
<div style="position:absolute;left:142.94px;top:612.00px" class="cls_007"><span class="cls_007">longer than twenty-five characters.";</span></div>
<div style="position:absolute;left:112.96px;top:625.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:112.96px;top:639.00px" class="cls_007"><span class="cls_007">else if (propertyName == nameof(Price) && Price == 0)</span></div>
<div style="position:absolute;left:127.95px;top:652.50px" class="cls_007"><span class="cls_007">error = "Please enter a valid price for the product.";</span></div>
<div style="position:absolute;left:112.96px;top:666.00px" class="cls_007"><span class="cls_007">return error;</span></div>
<div style="position:absolute;left:97.96px;top:679.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:82.97px;top:693.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:706.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:720.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:740.25px" class="cls_004"><span class="cls_004">Here we have a basic </span><span class="cls_007">Product</span><span class="cls_004"> class that extends our new base class. The only job that</span></div>
<div style="position:absolute;left:5.00px;top:758.25px" class="cls_004"><span class="cls_004">each derived class that wants to participate in the validation process needs to do is to</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:256640px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background322.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_004"><span class="cls_004">override the class indexer and supply details regarding their relevant validation logic.</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">In the indexer, we first set the </span><span class="cls_007">error</span><span class="cls_004"> field to an empty string. Note that this is an essential</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_004"><span class="cls_004">part of this implementation, as without it, any triggered validation errors would never be</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">cleared. There are a number of ways to implement this method, with several different</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">abstractions being possible. However, all implementations require validation logic to be run</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">when this property is called.</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">In our particular example, we simply use an </span><span class="cls_007">if</span><span class="cls_004"> statement to check for errors in each</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">property, although a </span><span class="cls_007">switch</span><span class="cls_004"> statement works just as well here. The first condition checks</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">the value of the </span><span class="cls_007">propertyName</span><span class="cls_004"> input parameter, while multiple validation rules per property</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">can be handled with inner </span><span class="cls_007">if</span><span class="cls_004"> statements.</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">If the </span><span class="cls_007">propertyName</span><span class="cls_004"> input parameter equals </span><span class="cls_007">Name</span><span class="cls_004">, then we first check to ensure that it has</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">some value and provide an error message in case of failure. If the property value is not null</span></div>
<div style="position:absolute;left:5.00px;top:219.75px" class="cls_004"><span class="cls_004">or empty, then a second validation condition checks that the length is no longer than twenty-</span></div>
<div style="position:absolute;left:5.00px;top:237.75px" class="cls_004"><span class="cls_004">five characters, which simulates a particular database constraint that we may have.</span></div>
<div style="position:absolute;left:5.00px;top:255.75px" class="cls_004"><span class="cls_004">If the </span><span class="cls_007">propertyName</span><span class="cls_004"> input parameter equals </span><span class="cls_007">Price</span><span class="cls_004">, then we simply check that a valid,</span></div>
<div style="position:absolute;left:5.00px;top:273.75px" class="cls_004"><span class="cls_004">positive value has been entered and provide another error message in case of failure. If we</span></div>
<div style="position:absolute;left:5.00px;top:291.75px" class="cls_004"><span class="cls_004">had further properties in this class, then we would simply add further </span><span class="cls_007">if</span><span class="cls_004"> conditions,</span></div>
<div style="position:absolute;left:5.00px;top:309.75px" class="cls_004"><span class="cls_004">checking their property names, and further relevant validation checks.</span></div>
<div style="position:absolute;left:5.00px;top:327.75px" class="cls_004"><span class="cls_004">Now that we have our validatable class, let's add a new View and View Model and the</span></div>
<div style="position:absolute;left:5.00px;top:345.75px" class="cls_007"><span class="cls_007">DataTemplate</span><span class="cls_004"> in the </span><span class="cls_007">App.xaml</span><span class="cls_004"> file that connects the two, to demonstrate what else we need</span></div>
<div style="position:absolute;left:5.00px;top:363.75px" class="cls_004"><span class="cls_004">to do to get our validation logic connected to the data in the UI. Let's first see the</span></div>
<div style="position:absolute;left:5.00px;top:381.75px" class="cls_007"><span class="cls_007">ProductViewModel</span><span class="cls_004"> class:</span></div>
<div style="position:absolute;left:52.98px;top:405.00px" class="cls_007"><span class="cls_007">using CompanyName.ApplicationName.DataModels;</span></div>
<div style="position:absolute;left:52.98px;top:432.00px" class="cls_007"><span class="cls_007">namespace CompanyName.ApplicationName.ViewModels</span></div>
<div style="position:absolute;left:52.98px;top:445.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:67.97px;top:459.00px" class="cls_007"><span class="cls_007">public class ProductViewModel : BaseViewModel</span></div>
<div style="position:absolute;left:67.97px;top:472.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:82.97px;top:486.00px" class="cls_007"><span class="cls_007">private Product product = new Product();</span></div>
<div style="position:absolute;left:82.97px;top:513.00px" class="cls_007"><span class="cls_007">public Product Product</span></div>
<div style="position:absolute;left:82.97px;top:526.50px" class="cls_007"><span class="cls_007">{</span></div>
<div style="position:absolute;left:97.96px;top:540.00px" class="cls_007"><span class="cls_007">get { return product; }</span></div>
<div style="position:absolute;left:97.96px;top:553.50px" class="cls_007"><span class="cls_007">set { if (product != value) { product = value;</span></div>
<div style="position:absolute;left:112.96px;top:567.00px" class="cls_007"><span class="cls_007">NotifyPropertyChanged(); } }</span></div>
<div style="position:absolute;left:82.97px;top:580.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:67.97px;top:594.00px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:52.98px;top:607.50px" class="cls_007"><span class="cls_007">}</span></div>
<div style="position:absolute;left:5.00px;top:627.75px" class="cls_004"><span class="cls_004">The </span><span class="cls_007">ProductViewModel</span><span class="cls_004"> class simply defines a single </span><span class="cls_007">Product</span><span class="cls_004"> object and exposes it via the</span></div>
<div style="position:absolute;left:5.00px;top:645.75px" class="cls_007"><span class="cls_007">Product</span><span class="cls_004"> property. Let's now see the related View.</span></div>
<div style="position:absolute;left:52.98px;top:669.00px" class="cls_007"><span class="cls_007"><UserControl</span></div>
<div style="position:absolute;left:52.98px;top:682.50px" class="cls_007"><span class="cls_007">x:Class="CompanyName.ApplicationName.Views.ProductView"</span></div>
<div style="position:absolute;left:67.97px;top:696.00px" class="cls_007"><span class="cls_007">xmlns="</span><A HREF="http://schemas.microsoft.com/winfx/2006/xaml/presentation"/">http://schemas.microsoft.com/winfx/2006/xaml/presentation"</A> </div>
<div style="position:absolute;left:67.97px;top:709.50px" class="cls_007"><span class="cls_007">xmlns:x="</span><A HREF="http://schemas.microsoft.com/winfx/2006/xaml"/">http://schemas.microsoft.com/winfx/2006/xaml"</A> </div>
<div style="position:absolute;left:67.97px;top:723.00px" class="cls_007"><span class="cls_007">xmlns:mc="</span><A HREF="http://schemas.openxmlformats.org/markup-/">http://schemas.openxmlformats.org/markup-</A> </div>
<div style="position:absolute;left:52.98px;top:736.50px" class="cls_007"><span class="cls_007">compatibility/2006"</span></div>
<div style="position:absolute;left:67.97px;top:750.00px" class="cls_007"><span class="cls_007">xmlns:d="</span><A HREF="http://schemas.microsoft.com/expression/blend/2008"/">http://schemas.microsoft.com/expression/blend/2008"</A> </div>
<div style="position:absolute;left:67.97px;top:763.50px" class="cls_007"><span class="cls_007">mc:Ignorable="d" FontSize="14" Width="600"></span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:257442px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background323.jpg" width=612 height=792></div>
<div style="position:absolute;left:67.97px;top:3.00px" class="cls_007"><span class="cls_007"><Grid Margin="20"></span></div>
<div style="position:absolute;left:82.97px;top:16.50px" class="cls_007"><span class="cls_007"><Grid.Resources></span></div>
<div style="position:absolute;left:97.96px;top:30.00px" class="cls_007"><span class="cls_007"><Style x:Key="LabelStyle" TargetType="{x:Type TextBlock}"></span></div>
<div style="position:absolute;left:112.96px;top:43.50px" class="cls_007"><span class="cls_007"><Setter Property="HorizontalAlignment" Value="Right" /></span></div>
<div style="position:absolute;left:112.96px;top:57.00px" class="cls_007"><span class="cls_007"><Setter Property="VerticalAlignment" Value="Center" /></span></div>
<div style="position:absolute;left:112.96px;top:70.50px" class="cls_007"><span class="cls_007"><Setter Property="Margin" Value="0,0,10,10" /></span></div>
<div style="position:absolute;left:97.96px;top:84.00px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:97.96px;top:97.50px" class="cls_007"><span class="cls_007"><Style x:Key="TextBoxStyle" TargetType="{x:Type TextBox}"></span></div>
<div style="position:absolute;left:112.96px;top:111.00px" class="cls_007"><span class="cls_007"><Setter Property="SnapsToDevicePixels" Value="True" /></span></div>
<div style="position:absolute;left:112.96px;top:124.50px" class="cls_007"><span class="cls_007"><Setter Property="VerticalAlignment" Value="Center" /></span></div>
<div style="position:absolute;left:112.96px;top:138.00px" class="cls_007"><span class="cls_007"><Setter Property="Margin" Value="0,0,0,10" /></span></div>
<div style="position:absolute;left:112.96px;top:151.50px" class="cls_007"><span class="cls_007"><Setter Property="Padding" Value="1.5,2" /></span></div>
<div style="position:absolute;left:97.96px;top:165.00px" class="cls_007"><span class="cls_007"></Style></span></div>
<div style="position:absolute;left:82.97px;top:178.50px" class="cls_007"><span class="cls_007"></Grid.Resources></span></div>
<div style="position:absolute;left:82.97px;top:192.00px" class="cls_007"><span class="cls_007"><Grid.RowDefinitions></span></div>
<div style="position:absolute;left:97.96px;top:205.50px" class="cls_007"><span class="cls_007"><RowDefinition Height="Auto" /></span></div>
<div style="position:absolute;left:97.96px;top:219.00px" class="cls_007"><span class="cls_007"><RowDefinition Height="Auto" /></span></div>
<div style="position:absolute;left:82.97px;top:232.50px" class="cls_007"><span class="cls_007"></Grid.RowDefinitions></span></div>
<div style="position:absolute;left:82.97px;top:246.00px" class="cls_007"><span class="cls_007"><Grid.ColumnDefinitions></span></div>
<div style="position:absolute;left:97.96px;top:259.50px" class="cls_007"><span class="cls_007"><ColumnDefinition Width="Auto" /></span></div>
<div style="position:absolute;left:97.96px;top:273.00px" class="cls_007"><span class="cls_007"><ColumnDefinition /></span></div>
<div style="position:absolute;left:82.97px;top:286.50px" class="cls_007"><span class="cls_007"></Grid.ColumnDefinitions></span></div>
<div style="position:absolute;left:82.97px;top:300.00px" class="cls_007"><span class="cls_007"><TextBlock Text="Name" Style="{StaticResource LabelStyle}" /></span></div>
<div style="position:absolute;left:82.97px;top:313.50px" class="cls_007"><span class="cls_007"><TextBox Grid.Column="1" Text="{Binding Product.Name,</span></div>
<div style="position:absolute;left:97.96px;top:327.00px" class="cls_007"><span class="cls_007">UpdateSourceTrigger=PropertyChanged,</span></div>
<div style="position:absolute;left:52.98px;top:340.50px" class="cls_007"><span class="cls_007">ValidatesOnDataErrors=True}"</span></div>
<div style="position:absolute;left:97.96px;top:354.00px" class="cls_007"><span class="cls_007">Style="{StaticResource TextBoxStyle}" /></span></div>
<div style="position:absolute;left:82.97px;top:367.50px" class="cls_007"><span class="cls_007"><TextBlock Grid.Row="1" Text="Price"</span></div>
<div style="position:absolute;left:97.96px;top:381.00px" class="cls_007"><span class="cls_007">Style="{StaticResource LabelStyle}" /></span></div>
<div style="position:absolute;left:82.97px;top:394.50px" class="cls_007"><span class="cls_007"><TextBox Grid.Row="1" Grid.Column="1" Text="{Binding</span></div>
<div style="position:absolute;left:52.98px;top:408.00px" class="cls_007"><span class="cls_007">Product.Price,</span></div>
<div style="position:absolute;left:97.96px;top:421.50px" class="cls_007"><span class="cls_007">UpdateSourceTrigger=PropertyChanged,</span></div>
<div style="position:absolute;left:52.98px;top:435.00px" class="cls_007"><span class="cls_007">ValidatesOnDataErrors=True}"</span></div>
<div style="position:absolute;left:97.96px;top:448.50px" class="cls_007"><span class="cls_007">Style="{StaticResource TextBoxStyle}" /></span></div>
<div style="position:absolute;left:67.97px;top:462.00px" class="cls_007"><span class="cls_007"></Grid></span></div>
<div style="position:absolute;left:52.98px;top:475.50px" class="cls_007"><span class="cls_007"></UserControl></span></div>
<div style="position:absolute;left:5.00px;top:508.50px" class="cls_004"><span class="cls_004">In this example, note that we have added some styles into the </span><span class="cls_007">Grid.Resources</span><span class="cls_004"> section for</span></div>
<div style="position:absolute;left:5.00px;top:526.50px" class="cls_004"><span class="cls_004">completeness, although in a production application, these styles would be declared in the</span></div>
<div style="position:absolute;left:5.00px;top:544.50px" class="cls_004"><span class="cls_004">application resources instead, where all Views would have access to them.</span></div>
<div style="position:absolute;left:5.00px;top:562.50px" class="cls_004"><span class="cls_004">In the XAML, we have a typical two column </span><span class="cls_007">Grid</span><span class="cls_004"> panel, with two rows. The two </span><span class="cls_007">TextBlock</span></div>
<div style="position:absolute;left:5.00px;top:580.50px" class="cls_004"><span class="cls_004">labels have the </span><span class="cls_007">LabelStyle</span><span class="cls_004"> style applied and the two </span><span class="cls_007">TextBox</span><span class="cls_004"> input controls have the</span></div>
<div style="position:absolute;left:5.00px;top:598.50px" class="cls_007"><span class="cls_007">TextBoxStyle</span><span class="cls_004"> style applied. The binding applied to each </span><span class="cls_007">TextBox.Text</span><span class="cls_004"> property has two</span></div>
<div style="position:absolute;left:5.00px;top:616.50px" class="cls_004"><span class="cls_004">important properties set on it.</span></div>
<div style="position:absolute;left:5.00px;top:634.50px" class="cls_004"><span class="cls_004">The first is the </span><span class="cls_007">UpdateSourceTrigger</span><span class="cls_004"> property and this controls when the data source is</span></div>
<div style="position:absolute;left:5.00px;top:652.50px" class="cls_004"><span class="cls_004">updated and therefore, also when validation occurs. If you remember, a value of</span></div>
<div style="position:absolute;left:5.00px;top:670.50px" class="cls_007"><span class="cls_007">PropertyChanged</span><span class="cls_004"> causes updates to occur as soon as the data bound property value</span></div>
<div style="position:absolute;left:5.00px;top:688.50px" class="cls_004"><span class="cls_004">changes. An alternative value would be </span><span class="cls_007">LostFocus</span><span class="cls_004">, which cause updates to occur when the</span></div>
<div style="position:absolute;left:5.00px;top:706.50px" class="cls_004"><span class="cls_004">UI control loses focus.</span></div>
<div style="position:absolute;left:5.00px;top:724.50px" class="cls_004"><span class="cls_004">The other important property here is the </span><span class="cls_007">ValidatesOnDataErrors</span><span class="cls_004"> property, without which,</span></div>
<div style="position:absolute;left:5.00px;top:742.50px" class="cls_004"><span class="cls_004">our current example would not work. Setting this property to </span><span class="cls_007">true</span><span class="cls_004"> on a binding causes a</span></div>
<div style="position:absolute;left:5.00px;top:760.50px" class="cls_004"><span class="cls_004">built-in </span><span class="cls_007">DataErrorValidationRule</span><span class="cls_004"> element to be implicitly added to the</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:258244px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background324.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_007"><span class="cls_007">Binding.ValidationRules</span><span class="cls_004"> collection.</span></div>
<div style="position:absolute;left:5.00px;top:21.75px" class="cls_004"><span class="cls_004">As the data bound value changes, this element will check for errors raised by the</span></div>
<div style="position:absolute;left:5.00px;top:39.75px" class="cls_007"><span class="cls_007">IDataErrorInfo</span><span class="cls_004"> interface. It does this by calling the indexer in our data model with the</span></div>
<div style="position:absolute;left:5.00px;top:57.75px" class="cls_004"><span class="cls_004">name of the data bound property each time the data source is updated. Therefore, in this</span></div>
<div style="position:absolute;left:5.00px;top:75.75px" class="cls_004"><span class="cls_004">basic example, the developers would be responsible for setting this property to </span><span class="cls_007">true</span><span class="cls_004"> on</span></div>
<div style="position:absolute;left:5.00px;top:93.75px" class="cls_004"><span class="cls_004">each binding to make the validation work.</span></div>
<div style="position:absolute;left:5.00px;top:111.75px" class="cls_004"><span class="cls_004">When using a value of </span><span class="cls_007">PropertyChanged</span><span class="cls_004"> for the </span><span class="cls_007">UpdateSourceTrigger</span><span class="cls_004"> property, along with</span></div>
<div style="position:absolute;left:5.00px;top:129.75px" class="cls_004"><span class="cls_004">the fact that we validate each time the properties change, we have the benefit of immediate</span></div>
<div style="position:absolute;left:5.00px;top:147.75px" class="cls_004"><span class="cls_004">updates of errors. However, this method of validation works in a pre-emptive manner, with</span></div>
<div style="position:absolute;left:5.00px;top:165.75px" class="cls_004"><span class="cls_004">all validation errors being shown before the user has a chance to enter any data. This can</span></div>
<div style="position:absolute;left:5.00px;top:183.75px" class="cls_004"><span class="cls_004">be somewhat off-putting to a user, so let's take a quick look at our example when it first</span></div>
<div style="position:absolute;left:5.00px;top:201.75px" class="cls_004"><span class="cls_004">starts.</span></div>
<div style="position:absolute;left:5.00px;top:312.75px" class="cls_004"><span class="cls_004">As you can see, it's clear that there are some problems, but it's unclear as to what they</span></div>
<div style="position:absolute;left:5.00px;top:330.75px" class="cls_004"><span class="cls_004">are. So far, we have no output for our error messages. One common output that we could</span></div>
<div style="position:absolute;left:5.00px;top:348.75px" class="cls_004"><span class="cls_004">use would be the tooltips of the various form controls.</span></div>
<div style="position:absolute;left:5.00px;top:366.75px" class="cls_004"><span class="cls_004">We could add a trigger to our </span><span class="cls_007">TextBoxStyle</span><span class="cls_004"> style that listened to the </span><span class="cls_007">Validation.HasError</span></div>
<div style="position:absolute;left:5.00px;top:384.75px" class="cls_004"><span class="cls_004">Attached Property and set the textbox's tooltip to the </span><span class="cls_007">ErrorContent</span><span class="cls_004"> property of the error</span></div>
<div style="position:absolute;left:5.00px;top:402.75px" class="cls_004"><span class="cls_004">whenever one was present. This is how Microsoft demonstrates how to do this on their</span></div>
<div style="position:absolute;left:5.00px;top:420.75px" class="cls_004"><span class="cls_004">MSDN website:</span></div>
<div style="position:absolute;left:52.98px;top:444.00px" class="cls_007"><span class="cls_007"><Style.Triggers></span></div>
<div style="position:absolute;left:67.97px;top:457.50px" class="cls_007"><span class="cls_007"><Trigger Property="Validation.HasError" Value="True"></span></div>
<div style="position:absolute;left:82.97px;top:471.00px" class="cls_007"><span class="cls_007"><Setter Property="ToolTip" Value="{Binding (Validation.Errors)</span></div>
<div style="position:absolute;left:52.98px;top:484.50px" class="cls_007"><span class="cls_007">[0].</span></div>
<div style="position:absolute;left:97.96px;top:498.00px" class="cls_007"><span class="cls_007">ErrorContent, RelativeSource={RelativeSource Self}}" /></span></div>
<div style="position:absolute;left:67.97px;top:511.50px" class="cls_007"><span class="cls_007"></Trigger></span></div>
<div style="position:absolute;left:52.98px;top:525.00px" class="cls_007"><span class="cls_007"></Style.Triggers></span></div>
<div style="position:absolute;left:5.00px;top:545.25px" class="cls_004"><span class="cls_004">Note that we use brackets in the binding path for the </span><span class="cls_007">Validation.Errors</span><span class="cls_004"> collection because</span></div>
<div style="position:absolute;left:5.00px;top:563.25px" class="cls_004"><span class="cls_004">it is an Attached Property and that we use the </span><span class="cls_007">RelativeSource.Self</span><span class="cls_004"> instance because we</span></div>
<div style="position:absolute;left:5.00px;top:581.25px" class="cls_004"><span class="cls_004">want to target the </span><span class="cls_007">Errors</span><span class="cls_004"> collection of the </span><span class="cls_007">TextBox</span><span class="cls_004"> control itself. Also note that this example</span></div>
<div style="position:absolute;left:5.00px;top:599.25px" class="cls_004"><span class="cls_004">only displays the first </span><span class="cls_007">ValidationError</span><span class="cls_004"> object in the </span><span class="cls_007">Errors</span><span class="cls_004"> collection.</span></div>
<div style="position:absolute;left:5.00px;top:617.25px" class="cls_004"><span class="cls_004">Using this style on our data bound textboxes helps to provide the user with further</span></div>
<div style="position:absolute;left:5.00px;top:635.25px" class="cls_004"><span class="cls_004">information when they position their mouse cursor over the relevant control(s).</span></div>
<div style="position:absolute;left:5.00px;top:746.25px" class="cls_004"><span class="cls_004">However, when there are no validation errors to display, an error will be seen in the </span><span class="cls_005">Output</span></div>
<div style="position:absolute;left:5.00px;top:765.00px" class="cls_004"><span class="cls_004">window of Visual Studio, because we are attempting to view the first error from the</span></div>
</div>
<div style="position:absolute;left:50%;margin-left:-306px;top:259046px;width:612px;height:792px;border-style:outset;overflow:hidden">
<div style="position:absolute;left:0px;top:0px">
<img src="cce2b07a-fafd-11e9-9d71-0cc47a792c0a_id_cce2b07a-fafd-11e9-9d71-0cc47a792c0a_files/background325.jpg" width=612 height=792></div>
<div style="position:absolute;left:5.00px;top:3.75px" class="cls_007"><span class="cls_007">Validation.Errors</span><span class="cls_004"> Attached Property collection and it does not exist:</span></div>
<div style="position:absolute;left:52.98px;top:27.00px" class="cls_007"><span class="cls_007">System.Windows.Data Error: 17 : Cannot get 'Item[]' value (type</span></div>
<div style="position:absolute;left:52.98px;top:40.50px" class="cls_007"><span class="cls_007">'ValidationError') from '(Validation.Errors)' (type</span></div>
<div style="position:absolute;left:52.98px;top:54.00px" class="cls_007"><span class="cls_007">'ReadOnlyObservableCollection1’). BindingExpression:Path=(Validation.Errors)[0].ErrorContent; DataItem=‘TextBox’
(Name=“);
target element is ‘TextBox’ (Name=“); target property is ‘ToolTip’
(type ‘Object’) ArgumentOutOfRangeException:
‘System.ArgumentOutOfRangeException: Specified argument was out of
the range of valid values.
Parameter name: index’
There are a number of ways to avoid this error, such as simply displaying the whole
collection, and we’ll see an example of this later in the chapter. However, the simplest way
is to make use of the CurrentItem property of the ICollectionView object that is implicitly
used to wrap IEnumerable data collections that are data bound to ItemsControl elements.
This is similar to the way that a ListBox will implicitly wrap our data bound data items in
ListBoxItem elements. The implementation of the ICollectionView interface that wraps
our data collection is primarily used to enable sorting, filtering and grouping of the data,
without affecting the actual data, but its CurrentItem property is a bonus in this situation.
With it, we can replace the indexer that was causing us a problem when there were no
validation errors. Now, when there are no errors, the CurrentItem property will return null,
rather than throwing an exception and so, despite Microsoft’s own examples showing the
use of the indexer, this is a far better solution.
<Setter Property=“ToolTip” Value=“{Binding (Validation.Errors).
CurrentItem.ErrorContent, RelativeSource={RelativeSource Self}}”
/>
Nevertheless, if an end user does not know to place their mouse cursor over the control to
see the tooltip, then the situation is still not improved. Therefore, this initial implementation
still has room for improvement. Another shortcoming of this interface is that it was designed
to be atomic, as it only deals with a single error per property at a time.
In our example, we want to validate that the Name property is not only entered, but also has
a valid length. In the order that we declared our two validation conditions for this property,
the first error will be raised when the field in the UI is empty and the second will be raised if
the entered value is too long. As the entered value cannot be both non-existent and too long
at the same time, having only a single reported error at one time is not a problem in this
particular example.
However, if we had a property that had multiple validation conditions, such as a maximum
length and a particular format, then with the usual IDataErrorInfo interface implementation,
we’d only be able to view one of these errors at once. However, despite this limitation, we
can still improve this basic implementation. Let’s see how we can do this:
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;

using CompanyName.ApplicationName.Extensions;
namespace CompanyName.ApplicationName.DataModels
{
public abstract class BaseValidationModelExtended :
INotifyPropertyChanged, IDataErrorInfo
{
protected ObservableCollection<string> errors =
new ObservableCollection<string>();
protected ObservableCollection<string> externalErrors =
new ObservableCollection<string>();
protected BaseValidationModelExtended()
{
ExternalErrors.CollectionChanged +=
ExternalErrors_CollectionChanged;
}
public virtual ObservableCollection<string> Errors => errors;
public ObservableCollection<string> ExternalErrors =>
externalErrors;
public virtual bool HasError => errors != null && Errors.Any();
#region IDataErrorInfo Members
public string Error
{
get
{
if (!HasError) return string.Empty;
StringBuilder errors = new StringBuilder();
Errors.ForEach(e =>
errors.AppendUniqueOnNewLineIfNotEmpty(e));
return errors.ToString();
}
}
public virtual string this[string propertyName] =>
string.Empty;
#endregion
#region INotifyPropertyChanged Members
public virtual event PropertyChangedEventHandler
PropertyChanged;
protected virtual void NotifyPropertyChanged(
params string[] propertyNames)
{
if (PropertyChanged != null)
{
foreach (string propertyName in propertyNames)
{
if (propertyName != nameof(HasError))
PropertyChanged(this,

new PropertyChangedEventArgs(propertyName));
}
PropertyChanged(this,
new PropertyChangedEventArgs(nameof(HasError)));
}
}
protected virtual void NotifyPropertyChanged(
[CallerMemberName]string propertyName = “”)
{
if (PropertyChanged != null)
{
if (propertyName != nameof(HasError)) PropertyChanged(this,
new PropertyChangedEventArgs(propertyName));
PropertyChanged(this,
new PropertyChangedEventArgs(nameof(HasError)));
}
}
#endregion
private void ExternalErrors_CollectionChanged(object sender,
NotifyCollectionChangedEventArgs e) =>
NotifyPropertyChanged(nameof(Errors));
}
}
In this example, we add two collections to hold error messages; the Errors collection
property contains validation errors that are generated within the derived class and the
ExternalErrors collection property holds externally generated validation errors, typically
from a parent View Model.
In the constructor, we attach the ExternalErrors_CollectionChanged event handler to the
CollectionChanged event of the ExternalErrors collection property, so that it is notified
whenever items are added or removed from it.
After the declaration of the error collection properties, we see the HasError expression
bodied property, that checks whether the Errors collection contains any errors or not. Note
that we check the errors field for null, rather than the Errors property, because we do not
want to regenerate the error messages twice each time this property is called.
Next, we see the new implementation of the IDataErrorInfo interface. The class indexer
remains the same as the one from the previous implementation, but we see a difference in
the definition of the Error property, which now compiles a complete list of all errors, rather
than returning a single error message at a time.
In it, we first check whether any errors exist and return an empty string if not. If errors do
exist, we initialize a StringBuilder object and use our ForEach Extension method to iterate
through the Errors collection and append each of them to it, if they haven’t already been
included. We do this using another Extension method before returning the output, so let’s
see what that looks like now.
public static void AppendUniqueOnNewLineIfNotEmpty(
this StringBuilder stringBuilder, string text)
{

if (text.Trim().Length > 0 &&
!stringBuilder.ToString().Contains(text))
stringBuilder.AppendFormat(“{0}{1}”,
stringBuilder.ToString().Trim().
Length == 0 ? string.Empty : Environment.NewLine, text);
}
In our AppendUniqueOnNewLineIfNotEmpty Extension method, we first check that the input
value is not an empty string and that it is not already present in the StringBuilder object. If
the text input parameter is valid, we use the ternary operator to determine whether it is the
first value to be added and whether we need to precede it with a new line or not, before
adding the new, unique value.
Returning to our validation base class now, we see the new implementation of the
INotifyPropertyChanged interface. Note that we repeat our earlier base class example, by
raising the PropertyChanged event each time changes are registered for any other
properties, but unlike the previous example, we raise the HasError property here rather
than the HasChanges property.
We can combine both of these and raise the PropertyChanged event for both properties
each time we receive notification of changes to other properties if we desire. In this case,
the purpose is to call the HasError property, which will be used in the UI to display or hide
the control that displays the error messages and so, it will be updated after every
validatable property change.
At the bottom of our class, we see the expression bodied
ExternalErrors_CollectionChanged method, which calls the NotifyPropertyChanged
method for the Errors collection property. This notifies controls that are data bound to this
property that its value has changed and that they should retrieve that new value. Let’s see
an example implementation of this from our Product class now:
public override ObservableCollection<string> Errors
{
get
{
errors = new ObservableCollection<string>();
errors.AddUniqueIfNotEmpty(this[nameof(Name)]);
errors.AddUniqueIfNotEmpty(this[nameof(Price)]);
errors.AddRange(ExternalErrors);
return errors;
}
}
Therefore, when an error is externally added to the ExternalErrors collection, the
ExternalErrors_CollectionChanged method will be called and that notifies of changes to
the Errors property. This results in the property being called and the external error(s) being
added to the internal errors collection, along with any internal errors.
To get this particular implementation of the IDataErrorInfo interface to work, each data
model class will need to override this Errors property to add error messages from each
validated property. We provide a few Extension methods to make this task easier. As its
name implies, the AddUniqueIfNotEmpty method adds strings to the collection if they do not
already exist in it.

public static void AddUniqueIfNotEmpty(
this ObservableCollection<string> collection, string text)
{
if (!string.IsNullOrEmpty(text) && !collection.Contains(text))
collection.Add(text);
}
The AddRange method is another useful Extension method that simply iterates through the
range collection input parameter and adds them to the collection parameter one by one.
public static void AddRange<T>(this ICollection<T> collection,
ICollection<T> range)
{
foreach (T item in range) collection.Add(item);
}
In addition to implementing this new Errors collection property in their derived classes,
developers will also need to ensure that they notify of changes to it each time a validatable
property value is changed. We can do this using our overload of the
NotifyPropertyChanged method that takes multiple values.
public string Name
{
get { return name; }
set { if (name != value) { name = value;
NotifyPropertyChanged(nameof(Name), nameof(Errors)); } }
}
public decimal Price
{
get { return price; }
set { if (price != value) { price = value;
NotifyPropertyChanged(nameof(Price), nameof(Errors)); } }
}
The Errors property is responsible for calling the class indexer with the name of each of the
properties that we want to validate. Any error messages that are returned, including those
from the ExternalErrors collection property, are then added to the internal errors
collection.
In effect, we have replicated what the Validation class and the DataErrorValidationRule
element does in the UI, but in our data model instead. This means that we no longer have to
set the ValidatesOnDataErrors property to true on each binding. This is a better solution
when using MVVM, as we prefer to work with data, rather than UI elements, and now also
have full access to all of the data validation errors in our View Models.
Furthermore, we now have the ability to manually feed in error messages from our View
Models to our data models via the ExternalErrors collection property. This can be very
useful when we need to validate across a collection of data model objects.
For example, if we need to ensure that the name of each data model object is unique within
a collection of related objects, we can use this feature. Let’s update our ProductViewModel
example to see how we can accomplish this:
using System;
using System.ComponentModel;

using System.Linq;
using CompanyName.ApplicationName.DataModels;
using CompanyName.ApplicationName.DataModels.Collections;
namespace CompanyName.ApplicationName.ViewModels
{
public class ProductViewModel : BaseViewModel
{
private Products products = new Products();
public ProductViewModel()
{
Products.Add(new Product() { Id = Guid.NewGuid(),
Name = “Virtual Reality Headset”, Price = 14.99m });
Products.Add(new Product() { Id = Guid.NewGuid(),
Name = “Virtual Reality Headset” });
Products.CurrentItemChanged += Products_CurrentItemChanged;
Products.CurrentItem = Products.Last();
ValidateUniqueName(Products.CurrentItem);
}
public Products Products
{
get { return products; }
set { if (products != value) { products = value;
NotifyPropertyChanged(); } }
}
private void Products_CurrentItemChanged(Product oldProduct,
Product newProduct)
{
if (newProduct != null)
newProduct.PropertyChanged += Product_PropertyChanged;
if (oldProduct != null)
oldProduct.PropertyChanged -= Product_PropertyChanged;
}
private void Product_PropertyChanged(object sender,
PropertyChangedEventArgs e)
{
if (e.PropertyName == “Name”)
ValidateUniqueName(Products.CurrentItem);
}
private void ValidateUniqueName(Product product)
{
string errorMessage = “The product name must be unique”;
if (!IsProductNameUnique(product))
product.ExternalErrors.Add(errorMessage);
else product.ExternalErrors.Remove(errorMessage);
}
private bool IsProductNameUnique(Product product) =>
Products.Count(p => p.Id != product.Id && p.Name !=
string.Empty &&
p.Name == product.Name) == 0;
}
}

Our ProductViewModel class still extends the BaseViewModel class, but now it declares a
Products collection and adds the original Product object to it in the constructor, along with
an additional Product instance. The Products class simply extends our BaseCollection
class.
namespace CompanyName.ApplicationName.DataModels.Collections
{
public class Products : BaseCollection<Product> { }
}
In the class constructor, we first add a couple of test products to the Products collection
and then attach the Products_CurrentItemChanged method to its CurrentItemChanged
delegate. The BaseCollection class automatically sets the first item in each collection to
the CurrentItem property, so in order to set the second item as the current item, we call
the Last method on the Products collection and set that to its CurrentItem property.
This ensures that the Products_CurrentItemChanged method is called when setting the
second item as the current item and the Product_PropertyChanged handler is attached to it.
After this, we then call the ValidateUniqueName method that is described shortly, passing in
the current item.
After the declaration of the Products property, we see the Products_CurrentItemChanged
method, which will be called each time the value of the CurrentItem property is changed. In
it, we attach the Product_PropertyChanged method to the PropertyChanged event of the
new current Product object and detach it from the previous current Product item.
The Product_PropertyChanged method will be called each time any property of the related
Product object changes. In it, we simply call the ValidateUniqueName method if the
changed property was the Name property, as that is the property that we need to validate
for uniqueness.
The ValidateUniqueName method is responsible for adding or removing the error from the
ExternalErrors collection property of the product input parameter. It does this by checking
the result of the IsProductNameUnique method, which does the actual check for uniqueness.
In the expression bodied IsProductNameUnique method, we use LINQ to query the
Products collection and find out whether an existing item shares the same name or not. It
does this by checking that each item does not have the same identification number, or in
other words, is not the object being edited, but does have the same name and that the
name is not an empty string.
If any other products that have the same name are found, then the method returns false
and an error is added to the product’s ExternalErrors collection in the ValidateUniqueName
method. Let’s update our earlier ProductView now to better display these errors:
<UserControl
x:Class=“CompanyName.ApplicationName.Views.ProductView”
compatibility/2006”
xmlns:Converters=“clr-
namespace:CompanyName.ApplicationName.Converters;

assembly=CompanyName.ApplicationName.Converters”
mc:Ignorable=“d” d:DesignHeight=“300” Width=“600” FontSize=“14”>
<Grid Margin=“20”>
<Grid.Resources>
<Converters:BoolToVisibilityConverter
x:Key=“BoolToVisibilityConverter” />
<DataTemplate x:Key=“WrapTemplate”>
<TextBlock Text=“{Binding}” TextWrapping=“Wrap” />
</DataTemplate>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ListBox ItemsSource=“{Binding Products}” SelectedItem=”
{Binding
Products.CurrentItem}” DisplayMemberPath=“Name”
Margin=“0,0,20,0” />
<Grid Grid.Column=“1”>
<Grid.RowDefinitions>
<RowDefinition Height=“Auto” />
<RowDefinition Height=“Auto” />
<RowDefinition Height=“Auto” />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=“Auto” />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Border Grid.ColumnSpan=“2” BorderBrush=“Red”
BorderThickness=“2” Background=“#1FFF0000” CornerRadius=“5”
Visibility=“{Binding Products.CurrentItem.HasError,
Converter={StaticResource BoolToVisibilityConverter}}”
Margin=“0,0,0,10” Padding=“10”>
<ItemsControl ItemsSource=“{Binding
Products.CurrentItem.Errors}”
ItemTemplate=“{StaticResource WrapTemplate}” />
</Border>
<TextBlock Grid.Row=“1” Text=“Name”
Style=“{StaticResource LabelStyle}” />
<TextBox Grid.Row=“1” Grid.Column=“1”
Text=“{Binding Products.CurrentItem.Name,
UpdateSourceTrigger=PropertyChanged}”
Style=“{StaticResource TextBoxStyle}” />
<TextBlock Grid.Row=“2” Text=“Price”
Style=“{StaticResource LabelStyle}” />
<TextBox Grid.Row=“2” Grid.Column=“1”
Text=“{Binding Products.CurrentItem.Price, Delay=250,
UpdateSourceTrigger=PropertyChanged}”
Style=“{StaticResource TextBoxStyle}” />
</Grid>
</Grid>
</UserControl>
Note that the styles that were declared in the resources from the previous ProductView
example have been omitted for brevity, although they are still used in this example. In

addition, we defined a XAML namespace for our Converters project and declared a
BoolToVisibilityConverter instance and a simple data template to wrap the text of the
error items in our global error display.
In this example, we now have a Grid panel with two columns. In the left column, we have a
ListBox control and in the right, we have another Grid panel with our form fields. The
ItemsSource property of the ListBox control is data bound to the Products collection
property from our View Model and the SelectedItem property is data bound to its
CurrentItem property.
We set the DisplayMemberPath property to Name as a shortcut for creating a DataTemplate
for our Product class that outputs the name of each product. Alternatively, we could have
returned the value of the Name property from the ToString method in our Product class to
achieve the same result.
In the Grid panel on the right, we declare three rows and in the top one, we define a
Border element containing an ItemsControl object. Its ItemsSource property is data bound
to the Errors collection property of the item that is set to the CurrentItem property of the
Products collection and its ItemTemplate property is set to our new WrapTemplate data
template. The Visibility property of the border is data bound to the item’s HasError
property using the BoolToVisibilityConverter instance from the resources.
Therefore, when a change is made to a validated property of the item and an error is raised
in our validation base class, the PropertyChanged event is raised for the HasError property
and this alerts this binding to check the latest value and update its visibility value via the
applied BoolToVisibilityConverter instance accordingly.
Note that we use an ItemsControl here, because with this collection, we have no need for
the extra features that the ListBox control provides us with, such as a border, or the notion
of a selected item. The two rows underneath the error output contain the form fields from
the original example.
When this example is run, we’ll see two items that have the same name in our ListBox
control. As such, there will already be a validation error displayed that highlights this fact
and was added through the ExternalErrors collection in the View Model. In addition to this,
we’ll see another error, highlighting the fact that a valid price needs to be entered.
As the UpdateSourceTrigger property of the field bindings have been set to
PropertyChanged and the data bound properties are validated straight away, the errors will
immediately disappear and/or reappear as soon as we type in the relevant form fields. This
setting, along with the fact that we validate each time the properties change, makes our
validation work in a pre-emptive manner.
We can also change this to work only when a user presses a submit button, by setting the
UpdateSourceTrigger property to the Explicit value. However, this requires that we
access the data bound controls in the code behind files and so we tend to avoid this
approach when using the MVVM methodology.
BindingExpression bindingExpression =
NameOfTextBox.GetBindingExpression(TextBox.TextProperty);
bindingExpression.UpdateSource();
Alternatively, if we wanted to validate in this way when using MVVM, we could simply call

the validation code when the command that is data bound to the submit or save button is
executed instead. Let’s now take a look at the INotifyDataErrorInfo interface, to see how
it differs from the IDataErrorInfo interface.
Introducing the INotifyDataErrorInfo interface
The INotifyDataErrorInfo interface was added to the .NET Framework in .NET 4.5 to
address concerns over the previous IDataErrorInfo interface. Like the IDataErrorInfo
interface, the INotifyDataErrorInfo interface is also a simple affair, with only three
members for us to implement.
With this interface, we now have a HasErrors property that indicates whether the relevant
data model instance has any errors or not, a GetErrors method that replaces the indexer of
the IDataErrorInfo interface and retrieves the object’s error collection, and an
ErrorsChanged event to raise when the entity’s errors change.
We can see straight away that this interface was designed to work with multiple errors,
unlike the IDataErrorInfo interface. However, past this fact, it is unclear how this interface
should be implemented. Let’s take a look at one possible implementation now.
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using CompanyName.ApplicationName.Extensions;
namespace CompanyName.ApplicationName.DataModels
{
public abstract class BaseNotifyValidationModel :
INotifyPropertyChanged,
INotifyDataErrorInfo
{
private Dictionary<string, List<string>> allPropertyErrors =
new Dictionary<string, List<string>>();
protected Dictionary<string, List<string>> AllPropertyErrors =>
allPropertyErrors;
public abstract IEnumerable<string> this[string propertyName] {
get; }
public void NotifyPropertyChangedAndValidate(
params string[] propertyNames)
{
foreach (string propertyName in propertyNames)
NotifyPropertyChangedAndValidate(propertyName);
}
public void NotifyPropertyChangedAndValidate(
[CallerMemberName]string propertyName = “”)
{
NotifyPropertyChanged(propertyName);
Validate(propertyName, this[propertyName]);
}

public void Validate(string propertyName, IEnumerable<string>
error)
{
if (errors.Any())
errors.ForEach(e => AddValidationError(propertyName, e));
else if (AllPropertyErrors.ContainsKey(propertyName))
RemoveValidationError(propertyName);
}
private void AddValidationError(string propertyName, string
error)
{
if (AllPropertyErrors.ContainsKey(propertyName))
{
if (!AllPropertyErrors[propertyName].Contains(error))
{
AllPropertyErrors[propertyName].Add(error);
OnErrorsChanged(propertyName);
}
}
else
{
AllPropertyErrors.Add(propertyName, new List<string>() {
error });
OnErrorsChanged(propertyName);
}
}
private void RemoveValidationError(string propertyName)
{
AllPropertyErrors.Remove(propertyName);
OnErrorsChanged(propertyName);
}
#region INotifyDataErrorInfo Members
public event EventHandler<DataErrorsChangedEventArgs>
ErrorsChanged;
public void OnErrorsChanged(string propertyName) =>
ErrorsChanged?.Invoke(this,
new DataErrorsChangedEventArgs(propertyName));
public IEnumerable GetErrors(string propertyName)
{
List<string> propertyErrors = new List<string>();
if (string.IsNullOrEmpty(propertyName)) return
propertyErrors;
allPropertyErrors.TryGetValue(propertyName, out
propertyErrors);
return propertyErrors;
}
public bool HasErrors =>
allPropertyErrors.Any(p => p.Value != null && p.Value.Any());
#endregion

#region INotifyPropertyChanged Members
public virtual event PropertyChangedEventHandler
PropertyChanged;
protected virtual void NotifyPropertyChanged(
params string[] propertyNames)
{
if (PropertyChanged != null) propertyNames.ForEach(
p => PropertyChanged(this, new
PropertyChangedEventArgs(p)));
}
protected virtual void NotifyPropertyChanged(
[CallerMemberName]string propertyName = “”)
{
PropertyChanged?.Invoke(this,
new PropertyChangedEventArgs(propertyName));
}
#endregion
}
}
In our first implementation, we see the declaration of the allPropertyErrors backing field
and the AllPropertyErrors expression bodied property that returns it. For this collection,
we use the type Dictionary<string, List<string>>, where the name of each property in
error is used as the dictionary key, and multiple errors for that property can be stored in the
related string list.
We then see an abstract string indexer that returns an IEnumerable of type string, which is
responsible for returning multiple validation errors from derived classes, that relate to the
property specified by the propertyName input parameter. We’ll see how we can implement
this in the derived classes in the Varying Levels of Validation section shortly.
We add two convenient NotifyPropertyChangedAndValidate methods, that we can use to
both notify of changes to our property and to validate it in a single operation. In these
methods, we call our implementation of the NotifyPropertyChanged method and then our
private Validate method, passing the relevant property name to both and the indexer error
output to the Validate method.
If the errors collection input parameter in the Validate method contains any errors, we
iterate through them, calling the AddValidationError method to add each of them,
otherwise we call the RemoveValidationError method to remove any other errors, if they
exist.
Next, we see the definition of the AddValidationError method, where we first check for the
existence of an entry for the property name in the keys of the AllPropertyErrors dictionary
object. If one exists, we then check whether the error already exists within the related list
and if it doesn’t, we add it and raise the ErrorsChanged event.
If there is no existing entry, we add a new one, along with a new string list containing the
error, and raise the ErrorsChanged event. In the RemoveValidationError method, we
remove the entry for the property Name input parameter from the AllPropertyErrors

dictionary and raise the ErrorsChanged event.
Next, we see the required INotifyDataErrorInfo interface members. We declare the
ErrorsChanged event and the related OnErrorsChanged expression bodied method that
raises it using the null conditional operator, although this method is not technically part of the
interface and we are free to raise the event as we see fit.
In the GetErrors method, we are required to return the errors for the propertyName input
parameter and so, we utilize the TryGetValue method of the Dictionary class to attempt to
retrieve the relevant errors, if any exist. Note that attempting to retrieve values from a
Dictionary object using a non-existent key directly will raise a KeyNotFoundException error,
so we return the empty collection if the property name value is null or equals
string.Empty.
The simplified HasErrors expression bodied property follows and simply returns true if the
allPropertyErrors field contains any errors, or false otherwise. Finally, we complete the
class with our default implementation of the INotifyPropertyChanged interface. Note that
we can simply omit this if we intend this base class to extend another with its own
implementation of this interface.
If we remove the call to the Validate method from the constructor of the ProductViewModel
class, this implementation would no longer work in a pre-emptive manner. It would instead
initially hide any pre-existing validation errors, such as empty required values, until the user
makes changes and there is a problem. Therefore, empty required values would never
cause an error to be raised, unless a value was entered and then deleted, to once again be
empty.
We could instead declare a ValidateAllProperties method that our View Models can call
to force a new validation pass, either pre-emptively, before the user has a chance to enter
any data, or on the click of a save button once all fields have been filled. We’ll see an
example of this later in this chapter, but for now, let’s see the updated XAML of our
ProductView class:
<UserControl
x:Class=“CompanyName.ApplicationName.Views.ProductView”
compatibility/2006”
xmlns:Converters=“clr-
namespace:CompanyName.ApplicationName.Converters;
assembly=CompanyName.ApplicationName.Converters”
mc:Ignorable=“d” d:DesignHeight=“300” Width=“600” FontSize=“14”>
<Grid Margin=“20”>
<Grid.Resources>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ListBox ItemsSource=“{Binding Products}” SelectedItem=”
{Binding

Products.CurrentItem}” DisplayMemberPath=“Name”
Margin=“0,0,20,0” />
<Grid Grid.Column=“1”>
<Grid.RowDefinitions>
<RowDefinition Height=“Auto” />
<RowDefinition Height=“Auto” />
<RowDefinition Height=“Auto” />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=“Auto” />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Border Grid.ColumnSpan=“2” BorderBrush=“Red”
BorderThickness=“2” Background=“#1FFF0000” CornerRadius=“5”
Visibility=“{Binding Products.CurrentItem.HasErrors,
Converter={StaticResource BoolToVisibilityConverter}}”
Margin=“0,0,0,10” Padding=“10”>
<ItemsControl ItemsSource=“{Binding
Products.CurrentItem.Errors}”
ItemTemplate=“{StaticResource WrapTemplate}” />
</Border>
<TextBlock Grid.Row=“1” Text=“Name”
Style=“{StaticResource LabelStyle}” />
<TextBox Grid.Row=“1” Grid.Column=“1”
Text=“{Binding Products.CurrentItem.Name,
UpdateSourceTrigger=PropertyChanged,
ValidatesOnNotifyDataErrors=True}”
Style=“{StaticResource TextBoxStyle}” />
<TextBlock Grid.Row=“2” Text=“Price”
Style=“{StaticResource LabelStyle}” />
<TextBox Grid.Row=“2” Grid.Column=“1”
Text=“{Binding Products.CurrentItem.Price,
UpdateSourceTrigger=PropertyChanged,
ValidatesOnNotifyDataErrors=True, Delay=250}”
Style=“{StaticResource TextBoxStyle}” />
</Grid>
</Grid>
</UserControl>
Once again, note that the styles that were declared in the resources from the previous
ProductView example have been omitted here for brevity, although they are still used in this
example. Another point to note is that the Visibility property of the global error display’s
border has now been updated to work with the new HasErrors from the
INotifyDataErrorInfo interface, rather than our previous base class HasError property.
The only other change was made to the text binding of the two textboxes; when using the
INotifyDataErrorInfo interface, instead of setting the ValidatesOnDataErrors property to
true as before, we now need to set the ValidatesOnNotifyDataErrors property to true.
We’ll update this example again shortly, but before that, let’s explore another method of
providing validation logic.

Annotating data
The .NET Framework also provides us with an alternative, attribute-based validation system
in the System.ComponentModel.DataAnnotations namespace. It is mostly comprised of a
wide range of attribute classes that we can decorate our data model properties with, to
specify our validation rules. In addition to these attributes, it also includes a few validation
classes, which will investigate later.
As an example, let’s look at replicating the current validation rules from our Product class
with these data annotation attributes. We need to validate that the Name property is entered
and has a length of twenty-five characters or less, and that the Price property is more than
zero. For the Name property, we can use the RequiredAttribute and the
MaxLengthAttribute.
[Required(ErrorMessage = “Please enter the product name.”)]
[MaxLength(25, ErrorMessage = “The product name cannot be longer
than
twenty-five characters.“)]
public string Name
{
get { return name; }
set { if (name != value) { name = value;
NotifyPropertyChangedAndValidate(); } }
}
As with all attributes, we can omit the word Attribute when using them to decorate
properties with. Most of these data annotation attributes declare one or more constructors
with a number of optional parameters. The ErrorMessage input parameter is used in each to
set the message to output when the specified condition is not met.
The RequiredAttribute constructor has no input parameters and simply checks that the
data bound value is not null or empty. The constructor of the MaxLengthAttribute class
takes an integer, that specifies the maximum allowable length of the data bound value and it
will raise a ValidationError instance if the input value is longer.
For the Price property, we can make use of the RangeAttribute with a really high
maximum value, as there is no MinimumAttribute class available.
[Range(0.01, (double)decimal.MaxValue,
ErrorMessage = “Please enter a valid price for the product.”)]
public decimal Price
{
get { return price; }
set { if (price != value) { price = value;
NotifyPropertyChangedAndValidate(); } }
}
The constructor of the RangeAttribute class takes two double values, that specify the
minimum and maximum valid values and in this example, we set the minimum to one penny
and the maximum to the maximum decimal value, as our Price property is of type decimal.
Note that we could not use the RequiredAttribute class here, as numeric data bound
values will never be null or empty.
There are a large number of these data annotation attribute classes, covering the most

common validation situations, but when we have a requirement that does not have a pre-
existing attribute to help us, we can create our own custom attribute class by extending the
ValidationAttribute class. Let’s create an attribute that only validates a minimum value:
using System.ComponentModel.DataAnnotations;
namespace CompanyName.ApplicationName.DataModels.Attributes
{
public class MinimumAttribute : ValidationAttribute
{
private double minimumValue = 0.0;
public MinimumAttribute(double minimumValue)
{
this.minimumValue = minimumValue;
}
protected override ValidationResult IsValid(object value,
ValidationContext validationContext)
{
if (value.GetType() != typeof(decimal) ||
(decimal)value < (decimal)minimumValue)
{
string[] memberNames =
new string[] { validationContext.MemberName };
return new ValidationResult(ErrorMessage, memberNames);
}
return ValidationResult.Success;
}
}
}
When we extend the ValidationAttribute class, we only need to override the IsValid
method to return true or false, depending on our input value, which is specified by the
value input parameter. In our simple example, we first declare the minimumValue field to
store the target minimum allowable value to use during validation.
We populate this field in the class constructor, with the value that users of our class
provide. Next, we override the IsValid method that returns a ValidationResult instance.
In this method, we first check the type of the value input parameter and then cast it to
decimal, in order to compare it with the value of our minimumValue field.
Note that we have hardcoded this double type as the type of our minimum value, because
although our Price property is decimal, the decimal type is not considered primitive and
therefore cannot be used in an attribute. A better, more reusable solution, would be to
declare a number of constructors that accept different numerical types that could be used in
a wider range of situations and to update our IsValid method to be able to compare the
different types with the input value.
In our example, if the input value is either the incorrect type, or the cast value is less than
the value of the minimumValue field, we first create the memberNames variable and insert the
value of the MemberName property from the validationContext input parameter. We then
return a new instance of the ValidationResult class, inputting the used error message and
our memberNames collection.

If the input value is valid according to our particular validation logic, then we simply return
the ValidationResult.Success field to signify successful validation. Let’s see our new
attribute being used on the Price property of the Product class now:
[Minimum(0.01,
ErrorMessage = “Please enter a valid price for the product.”)]
public decimal Price
{
get { return price; }
set { if (price != value) { price = value;
NotifyPropertyChangedAndValidate(); } }
}
In effect, our new attribute will work exactly as the previously used RangeAttribute
instance, but it clearly demonstrates how we can create our own custom validation
attributes. Before we move on to see how we can read these errors with our code, let’s
first see how we can access the value of a second property from the data model in our
attribute, as this is a common requirement when validating:
PropertyInfo propertyInfo =
validationContext.ObjectType.GetProperty(otherPropertyName);
if (propertyInfo == null) throw new ArgumentNullException(
$“Unknown property: {otherPropertyName}“);
object otherPropertyValue =
propertyInfo.GetValue(validationContext.ObjectInstance);
This example assumes that we have added a reference to the System and
System.Reflection namespaces and declared a string field named otherPropertyName,
that is populated with the name of the other property name in the constructor. Using
reflection, we attempt to access the PropertyInfo object that relates to the specified
property name.
If the PropertyInfo object is null, we throw an ArgumentNullException object, alerting the
developer that they have used in non-existent property name. Otherwise, we use the
GetValue method of the PropertyInfo object to retrieve the value from the other property.
Now that we’ve seen how to use and create our own custom validation attributes, let’s see
how we can use them to validate our data model instances from one of their base classes:
ValidationContext validationContext = new ValidationContext(this);
validationContext.MemberName = propertyName;
List<ValidationResult> validationResults = new
List<ValidationResult>();
Validator.TryValidateObject(this, validationContext,
validationResults,
true);
We start by initializing a ValidationContext object, passing in the data model instance from
the base class. We can optionally set the MemberName property to set the name of the
property to validate. The context object is then passed to the TryValidateObject method of
the Validator class, in order to retrieve any validation errors from any of the data
annotation attributes.
We also initialize and pass a list of type ValidationResult into the TryValidateObject
method, which will get filled with errors for the current data object. Note that the fourth, bool

input parameter of this method specifies whether it will return errors for all properties, or
just for those that have been decorated with RequiredAttribute from the data annotations
namespace.
Later, we’ll see how we can incorporate this into our application framework’s base
validation class, but now let’s investigate how we can perform different levels of validation in
different scenarios.

Varying levels of validation
One thing that is not addressed by either of the .NET validation interfaces is the ability to
either turn validation on or off, or to set varying levels of validation. This can be useful in
several different scenarios, such as having different Views to edit different properties of a
data model object.
An example of this might be having a View that enables users to update the security
settings of a User object, where we want to validate that each property has a value, but
only for the properties that are currently displayed in the View. After all, there is no point in
informing the user that a certain field must be entered if they can’t do that in their current
View.
The solution is to define a number of levels of validation, in addition to the levels that
represent full and no validation. Let’s take a look at a simple ValidationLevel enumeration
that could fulfil this requirement.
namespace CompanyName.ApplicationName.DataModels.Enums
{
public enum ValidationLevel
{
None, Partial, Full
}
}
As we can see, in this simple example, we just have the three levels of validation, although
we could have added many more. However, in practice, we could still manage with this
enumeration. Let’s see how we could use it to implement multi-level validation in our
validation base class:
private ValidationLevel validationLevel = ValidationLevel.Full;
public ValidationLevel ValidationLevel
{
get { return validationLevel; }
set { if (validationLevel != value) { validationLevel = value; }
}
}
private void Validate(string propertyName, IEnumerable<string>
error)
{
if (ValidationLevel == ValidationLevel.None) return;
if (errors.Any())
errors.ForEach(e => AddValidationError(propertyName, e));
else if (AllPropertyErrors.ContainsKey(propertyName))
RemoveValidationError(propertyName);
}
We add a ValidationLevel property, with its validationLevel backing field that defaults to
the Full enumeration member, as that is the normal action. Then, in the Validate method,
we add a new line that simply exits the method if the ValidationLevel property is set to the
None enumeration member.
Finally, the developers of our application need to use the ValidationLevel property when

validating their properties in the data model classes. Imagine a scenario where users could
edit the names of our products directly in a collection control, or edit all of the product’s
properties in a separate View. Let’s update our basic Product class indexer to demonstrate
this:
public override IEnumerable<string> this[string propertyName]
{
get
{
List<string> errors = new List<string>();
if (propertyName == nameof(Name))
{
if (string.IsNullOrEmpty(Name))
errors.Add(“Please enter the product name.”);
else if (Name.Length > 25) errors.Add(“The product name
cannot be
longer than twenty-five characters.“);
if (Name.Length > 0 && char.IsLower(Name[0])) errors.Add(“The
first
letter of the product name must be a capital letter.“);
}
else if (propertyName == nameof(Price) &&
ValidationLevel == ValidationLevel.Full && Price == 0)
errors.Add(“Please enter a valid price for the product.”);
return errors;
}
}
Using our implementation of the INotifyDataErrorInfo interface, we first initialize a string
list named errors and then we check the value of the propertyName input parameter. As
this implementation enables us to return multiple validation errors per property, we need to
take care with our if and else statements.
For example, when the propertyName input parameter equals Name, we have two if
statements and one else statement. The first if statement verifies that the Name property
has a value, while the else statement checks that its value is no longer than twenty-five
characters. As these two conditions cannot possibly both be true at the same time, we tie
them together with the if…else statement.
On the other hand, the product name could be longer than twenty-five characters and start
with a lowercase letter and so, the next condition has its own if statement. The remaining
condition for the Price property is only to be validated when the ValidationLevel property
is set to the Full member and so, that is simply added as a further condition.
To trigger partial validation on a data model variable, we can simply set its ValidationLevel
property as follows:
product.ValidationLevel = ValidationLevel.Partial;

Incorporating multiple validation
techniques
Now that we’ve had a good look at the two validation interfaces, the data annotation
attributes and the ability to validate with different levels, let’s take a look at how we can
amalgamate these different techniques together.
Let’s create a BaseNotifyValidationModel class by copying what we have in our previous
implementation, to incorporate these new additions. First, we need to add some extra using
directives to the ones used in the previous implementation:
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel.DataAnnotations;
using CompanyName.ApplicationName.DataModels.Enums;
Next, we need to add our validationLevel and errors fields:
private ValidationLevel validationLevel = ValidationLevel.Full;
protected ObservableCollection<string> errors =
new ObservableCollection<string>();
We need to add a constructor, in which we attach the ExternalErrors_CollectionChanged
event handler to the CollectionChanged event of the ExternalErrors collection property, as
we did earlier:
protected BaseNotifyValidationModel()
{
ExternalErrors.CollectionChanged +=
ExternalErrors_CollectionChanged;
}
Now, let’s add the familiar ValidationLevel, Errors and the ExternalErrors properties,
along with the abstract ValidateAllProperties method.
public ValidationLevel ValidationLevel
{
get { return validationLevel; }
set { if (validationLevel != value) { validationLevel = value; }
}
}
public virtual ObservableCollection<string> Errors
{
get
{
errors = new ObservableCollection<string>();
IEnumerable<string> allErrors =
AllPropertyErrors.Values.SelectMany(e => e);
errors.Add(allErrors.Distinct());
ExternalErrors.Where(
e => !errors.Contains(e)).ForEach(e => errors.Add(e));
return errors;
}
}

public ObservableCollection<string> ExternalErrors { get; } =
new ObservableCollection<string>();
public abstract void ValidateAllProperties();
Note that in this implementation, users of our framework will no longer need to override the
Errors property in order to ensure that their validatable properties are validated. While we
still declare this property as virtual, so that it can be overridden if necessary, this base class
implementation already compiles all validation errors into the internal collection, ready for
display.
This time, we first clear the errors collection, before adding all of the unique errors from
each property error collection from the AllPropertyErrors property Dictionary object. We
then add any errors from the ExternalErrors collection, if they do not already exist in the
errors collection. This string Errors collection is primarily used because it is far easier to
data bind to in the UI.
After the new Errors property, we see the ExternalErrors auto property with its initializer
and the abstract ValidateAllProperties method that needs to be implemented in the
derived classes and can be called to force a new validation pass, either pre-emptively, or
on the click of a save button, once all fields have been filled.
Let’s see an example for our Product class, which we should call after initializing the data
collection in its constructor to instigate pre-emptive validation:
public override void ValidateAllProperties()
{
Validate(nameof(Name), nameof(Price));
}
After the ValidateAllProperties method, we need to declare a couple of Validate
methods, the first of which is a convenience method and simply calls the second, private
method that should replace our previous method with the identical signature:
public void Validate(params string[] propertyNames)
{
foreach (string propertyName in propertyNames)
Validate(propertyName, this[propertyName]);
}
private void Validate(string propertyName, IEnumerable<string>
errors)
{
if (ValidationLevel == ValidationLevel.None) return;
ValidationContext validationContext = new
ValidationContext(this);
List<ValidationResult> validationResults = new
List<ValidationResult>();
Validator.TryValidateObject(this, validationContext,
validationResults,
true);
IEnumerable<ValidationResult> propertyValidationResults =
validationResults.Where(v =>
v.MemberNames.Contains(propertyName));
propertyValidationResults.ForEach(
v => AddValidationError(propertyName, v.ErrorMessage));

if (errors.Any())
errors.ForEach(e => AddValidationError(propertyName, e));
else if (propertyValidationResults.Count() == 0 &&
AllPropertyErrors.ContainsKey(propertyName))
RemoveValidationError(propertyName);
NotifyPropertyChanged(nameof(Errors), nameof(HasErrors));
}
In this new Validate method, we incorporate the code that retrieves the validation errors
from any used data annotation attributes, that was introduced in the earlier Annotating data
section. We start by returning immediately if the ValidationLevel property is set to the
None member, otherwise, we retrieve the data annotation related validation errors.
We then filter just the errors that relate to the current property that is specified by the
propertyName input parameter and assign them to the propertyValidationResults
collection variable. Next, we iterate through this collection, calling the AddValidationError
method on each item.
If the errors collection input parameter contains any errors, we iterate through it, calling the
AddValidationError method to add each item. If the errors collection is empty, we check
that the propertyValidationResults collection is also empty and that the
AllPropertyErrors dictionary actually contains one or more errors. If it does, we call the
RemoveValidationError method to clear the dictionary entry.
Note that we have moved our call to notify of changes to our Errors and HasErrors
properties from our NotifyPropertyChanged method to this method, which is only called for
validatable properties and so, simplifies matters.
Finally, we just need to add the ExternalErrors_CollectionChanged method that is
referenced in the constructor. It simply notifies of changes to the Errors collection and the
HasError property, so that they will be updated each time an external error is added or
removed.
private void ExternalErrors_CollectionChanged(object sender,
NotifyCollectionChangedEventArgs e)
{
NotifyPropertyChanged(nameof(Errors), nameof(HasErrors));
}
Now, our base validation class will manage errors that are defined in the indexer of each
derived class, along with those defined in any data annotation attributes that may decorate
the class properties. This implementation enables us to display multiple validation errors per
property in our separate global error output collection control.

The HasErrors property can be used to set the visibility of such a collection control in the
UI, so that it can display the complete collection of errors, whenever any exist and hide it
when there are none. The last change that we need to make is to add an additional
condition into the HasErrors property that listens out for external errors as well the internally
generated ones.
public bool HasErrors => ExternalErrors.Any() ||
allPropertyErrors.Any(p => p.Value != null && p.Value.Any());
Let’s see how we can customize the way that we highlight these validation errors to the
users now.

Customizing the error template
In addition to the essential Errors and HasError properties, the Validation class also
declares an ErrorTemplate Attached Property of type ControlTemplate. The default
template assigned to this property is responsible for defining the red rectangle that
surrounds UI fields that have validation errors associated with them.
However, this property enables us to change this template and so, we are able to define
how validation errors are highlighted to the application users. As this property is an
Attached Property, this effectively means that we could apply a different template to be
displayed for each control in the UI. However, this cannot be recommended, because it
could make the application look less consistent.
This template actually uses an Adorner element to render its graphics in the adorner layer
on top of the related control in error. Therefore, in order to specify where our error visual(s)
should be rendered in relation to the related control, we need to declare an
AdornedElementPlaceholder element in the error template.
Let’s take a look at a simple example, where we define a slightly thicker, non-blurry border,
unlike the default one, and paint over the background of the related control with feint red for
added emphasis. We first need to define a ControlTemplate object in a suitable resource
section:
<ControlTemplate x:Key=“ErrorTemplate”>
<Border BorderBrush=“Red” BorderThickness=“2”
Background=“#1FFF0000”
SnapsToDevicePixels=“True”>
<AdornedElementPlaceholder />
</Border>
</ControlTemplate>
In this example, we declare the AdornedElementPlaceholder element inside a Border
element, so that the border will be rendered around the outside of the related control. Note
that without declaring this AdornedElementPlaceholder element, our border would resemble
a tiny red dot in the top left of the related control when an error occurred.
Let’s see how we apply this template, using our earlier example of the control that was data
bound to the Product.Price property and what it looks like now:
<TextBox Grid.Row=“2” Grid.Column=“1”
Text=“{Binding Products.CurrentItem.Price,
UpdateSourceTrigger=PropertyChanged,
ValidatesOnNotifyDataErrors=True, Delay=250}”
Style=“{StaticResource TextBoxStyle}”
Validation.ErrorTemplate=“{StaticResource ErrorTemplate}” />
If we wanted to position our error highlighting elements in a different position with relation to
the related control in error, we could use one of the panels to position them. Let’s take a

look at a slightly more advanced error template that we could use. Let’s start with declaring
some resources in a suitable resource section:
<ToolTip x:Key=“ValidationErrorsToolTip”>
<ItemsControl ItemsSource=“{Binding}”>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text=“{Binding ErrorContent}” />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ToolTip>
<ControlTemplate x:Key=“WarningErrorTemplate”>
<StackPanel Orientation=“Horizontal”
ToolTip=“{StaticResource ValidationErrorsToolTip}”>
<AdornedElementPlaceholder Margin=“0,0,2,0” />
<Image
Source=“pack://application:,,,/CompanyName.ApplicationName;
component/Images/Warning_16.png” Stretch=“None” />
</StackPanel>
</ControlTemplate>
In this example, we declare a ToolTip resource named ValidationErrorsToolTip. In it, we
declare an ItemsControl element to display all of the validation errors together. We define
a DataTemplate element in the ItemTemplate property, that will output the value of the
ErrorContent property of each ValidationError object in the Validation.Errors
collection. This collection will be implicitly set as the data context of the control template.
Next, we declare a ControlTemplate element to set to the ErrorTemplate property with the
key WarningErrorTemplate. In it, we define a horizontal StackPanel control and apply the
ValidationErrorsToolTip resource to its ToolTip property. Within the panel, we declare
the required AdornedElementPlaceholder element, followed by the warning icon taken from
the Visual Studio icon set that was discussed in the previous chapter.
We can apply this template using the ErrorTemplate property as follows:
<TextBox Grid.Row=“2” Grid.Column=“1”
Text=“{Binding Products.CurrentItem.Price,
UpdateSourceTrigger=PropertyChanged,
ValidatesOnNotifyDataErrors=True, Delay=250}”
Style=“{StaticResource TextBoxStyle}”
Validation.ErrorTemplate=“{StaticResource WarningErrorTemplate}”
/>
When a validation error now occurs on this textbox, it will look like this:

Avoiding UI-based validation errors
In the last example from the previous section, we data bound the whole Validation.Errors
collection to a tooltip in the error template for our textbox. We also data bound our own
Errors collection from our base class to the items control above the form fields.
Our Errors collection can display all of the errors for all of the properties in each data
model. However, the Validation.Errors collection has access to UI-based validation errors
that never make it back to the View Models. Take a look at the following example:
The UI-based validation error says Value ‘0t’ could not be converted and that explains
why the View Models never see this error. The type of value expected in the data bound
property is decimal, but an unconvertible value has been entered. Therefore, the input value
cannot be converted to a decimal and so, the data bound value is never updated.
However, the Validation.Errors collection is a UI element and each data bound control
has its own collection and so, we have no simple way to access them all from our View
Model classes. Furthermore, the ValidationError class is in the System.Windows.Controls
UI assembly, so we don’t want to add a reference of that to our ViewModels project.
Instead of trying to control the UI-based validation errors from the View Models, we can
alternatively extend controls, or define Attached Properties that restrict the ability of the
users to enter invalid data in the first place, thereby avoiding the need for UI-based
validation. Let’s take a look at one way that we can create a textbox that will only accept
numerical input, using our TextBoxProperties class:
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace CompanyName.ApplicationName.Views.Attached
{
public class TextBoxProperties : DependencyObject
{
#region IsNumericOnly
public static readonly DependencyProperty IsNumericOnlyProperty
=
DependencyProperty.RegisterAttached(“IsNumericOnly”,
typeof(bool), typeof(TextBoxProperties),
new UIPropertyMetadata(default(bool),

OnIsNumericOnlyChanged));
public static bool GetIsNumericOnly(DependencyObject
dependencyObject)
{
return
(bool)dependencyObject.GetValue(IsNumericOnlyProperty);
}
public static void SetIsNumericOnly(DependencyObject
dependencyObject,
bool value)
{
dependencyObject.SetValue(IsNumericOnlyProperty, value);
}
public static void OnIsNumericOnlyChanged(DependencyObject
dependencyObject, DependencyPropertyChangedEventArgs e)
{
TextBox textBox = (TextBox)dependencyObject;
bool newIsNumericOnlyValue = (bool)e.NewValue;
if (newIsNumericOnlyValue)
{
textBox.PreviewTextInput += TextBox_PreviewTextInput;
textBox.PreviewKeyDown += TextBox_PreviewKeyDown;
DataObject.AddPastingHandler(textBox, TextBox_Pasting);
}
else
{
textBox.PreviewTextInput -= TextBox_PreviewTextInput;
textBox.PreviewKeyDown -= TextBox_PreviewKeyDown;
DataObject.RemovePastingHandler(textBox, TextBox_Pasting);
}
}
private static void TextBox_PreviewTextInput(object sender,
TextCompositionEventArgs e)
{
string text = GetFullText((TextBox)sender, e.Text);
e.Handled = !IsTextValid(text);
}
private static void TextBox_PreviewKeyDown(object sender,
KeyEventArgs e)
{
TextBox textBox = (TextBox)sender;
e.Handled = e.Key == Key.Space || (textBox.Text.Length == 1
&&
(e.Key == Key.Delete || e.Key == Key.Back));
}
private static void TextBox_Pasting(object sender,
DataObjectPastingEventArgs e)
{
if (e.DataObject.GetDataPresent(typeof(string)))
{
string text = GetFullText((TextBox)sender,
(string)e.DataObject.GetData(typeof(string)));

if (!IsTextValid(text)) e.CancelCommand();
}
else e.CancelCommand();
}
private static string GetFullText(TextBox textBox, string
input)
{
return textBox.SelectedText.Length > 0 ?
string.Concat(textBox.Text.Substring(0,
textBox.SelectionStart),
input, textBox.Text.Substring(textBox.SelectionStart +
textBox.SelectedText.Length)) :
textBox.Text.Insert(textBox. SelectionStart, input);
}
private static bool IsTextValid(string text)
{
return Regex.Match(text, @“^-?\d.?\d$“).Success;
}
#endregion
}
}
Excluding the other, existing members from our TextBoxProperties class, we first declare
the IsNumericOnly Attached Property and its getter and setter methods and attach the
OnIsNumericOnlyChanged handler.
In the OnIsNumericOnlyChanged method, we first cast the dependencyObject input
parameter to a TextBox and then cast the NewValue property of the
DependencyPropertyChangedEventArgs class to the bool newIsNumericOnlyValue variable.
If the newIsNumericOnlyValue variable is true, we attach our event handlers for the
PreviewTextInput, PreviewKeyDown and DataObject.Pasting events. If the
newIsNumericOnlyValue variable is false, we detach the handlers.
We need to handle all of these events in order to create a textbox that can only enter
numerical values. The UIElement.PreviewTextInput event is raised when the textbox
receives a text input from any device, the Keyboard.PreviewKeyDown event occurs
specifically when a keyboard key is pressed and the DataObject.Pasting event is raised
when we paste from the clipboard.
The TextCompositionEventArgs object in the TextBox_PreviewTextInput handler method
only provides us with the last typed character through its Text property, along with
TextComposition details. At the stage that this tunneling event is called, the Text property
of the relevant textbox is not yet aware of this latest character.
Therefore, in order to correctly validate the whole entered text value, we need to combine
the existing value with this new character. We do that in the GetFullText method and pass
the returned value to the IsTextValid method.
We then set the inverted return value of the IsTextValid method to the Handled property of
the TextCompositionEventArgs input parameter. Note that we invert this bool value,

because setting the Handled property to true will stop the event from being routed any
further and result in the latest character not being accepted. Therefore, we do this when the
input value is invalid.
Next, we see the TextBox_PreviewKeyDown event handler method and in it, we again start
by casting the sender input parameter to a TextBox instance. We specifically need to
handle this event, because the PreviewTextInput event does not get raised when the
Space bar, Delete , or Backspace keys on the keyboard are pressed.
Therefore, we stop the event being routed any further by setting the Handled property of
the KeyEventArgs input parameter to true if the key pressed is the Space bar key, or if the
length of the entered text is a single character and the Delete or Backspace key is
pressed; this stops the user from deleting the last character from the textbox, which would
result in a UI-based validation error.
In the TextBox_Pasting handler method, we check whether the DataObject property that is
accessed from the DataObjectPastingEventArgs input parameter has any string data
available and call its CancelCommand method to cancel the paste operation if not.
If string data is present, we cast the sender input parameter to a TextBox instance and then
pass the data from the DataObject property to the GetFullText method to reconstruct the
whole entered string. We pass the reconstructed text to the IsTextValid method and if it is
invalid, then we call the CancelCommand method to cancel the paste operation.
Next is the GetFullText method, where the entered text from the textbox is reconstructed.
In this method, if any text is selected in the textbox, we rebuild the string by concatenating
the portion of text before the selection with the newly entered or pasted text and the portion
of text after the selection. Otherwise, we use the Insert method of the String class, along
with the textbox’s SelectionStart property to insert the new character into the appropriate
place in the string.
At the end of the class, we see the IsTextValid method, which simply returns the Success
property value of the Regex.Match method. The regular expression that we validate with is
as follows:
@“^-?\d.?\d$“.
The ampersand marks the string as a verbatim string literal, which is useful when using
characters that normally need to be escaped, the caret signifies the start of the input line,
the -? states that we can accept zero or one minus signs at the start, the \d indicates that
we can then have zero or more numerical digits, the .? specifies that zero or one periods
are then valid, the \d again indicates that we can then have zero or more numerical digits
and finally, the $ signifies the end of the input line.
When attached to an ordinary TextBox control, we can now only enter numeric values, but
both integer and decimal values are allowed. Continuing to use our earlier ProductView
example, we can attach our new property like this:
xmlns:Attached=“clr-
namespace:CompanyName.ApplicationName.Views.Attached”
<TextBox Grid.Row=“2” Grid.Column=“1”
Text=“{Binding Products.CurrentItem.Price,
UpdateSourceTrigger=PropertyChanged,

ValidatesOnNotifyDataErrors=True, Delay=250}”
Style=“{StaticResource TextBoxStyle}”
Validation.ErrorTemplate=“{StaticResource WarningErrorTemplate}”
Attached:TextBoxProperties.IsNumericOnly=“True” />
However, those that have been experimenting with this ProductView example may have
noticed something peculiar occurring when attempting to enter a price. In .NET 4.5,
Microsoft decided to introduce a breaking change to the way that data is entered into the
TextBox control when the binding UpdateSourceTrigger is set to PropertyChanged.
From .NET 4.5, we can no longer enter a numerical separator, neither a period nor a
comma, when we have data bound to a float, double, or decimal data type. There are a
number of ways around this, with the first being introduced with the change in .NET 4.5. A
new related property has been added to WPF, which we can set to address this issue.
The KeepTextBoxDisplaySynchronizedWithTextProperty property was added to the
FrameworkCompatibilityPreferences class, which indicates whether a textbox should
display the same as its data bound property or not. If we set this to false, it should return
the previous behavior, although in practice, there are still some side effects:
FrameworkCompatibilityPreferences.
KeepTextBoxDisplaySynchronizedWithTextProperty = false;
Note that we need to set this property very early in the application lifetime, such as in the
constructor of the App.xaml.cs file. Once set, it cannot be changed. Another way is to
avoid this problem is to set the UpdateSourceTrigger property to a value other than
PropertyChanged, however, this is no use if we want to validate or want our data source to
update with each key press.
<TextBox Text=“{Binding Products.CurrentItem.Price,
Style=“{StaticResource TextBoxStyle}”
UpdateSourceTrigger=LostFocus … />
Alternatively, we could simply data bind a string property to our textbox and perform our
own number parsing in our View Model. Another option would be to utilize the Delay
property of the Binding class that we discussed in Chapter 4, Becoming Proficient with
Data Binding. If we set this to a figure of just a few hundred milliseconds, it can give the
user enough time to enter their number including the decimal point:
<TextBox Text=“{Binding Products.CurrentItem.Price,
UpdateSourceTrigger=PropertyChanged, Delay=250}” … />
This is the option that we used in our examples, primarily because it is a simple and quick
fix for this problem. However, care should be taken when using this method with actual
monetary properties, as mistakes can easily be made if the user types slowly and does not
pay attention to the entered value.
A more robust solution would be to declare an IValueConverter implementation to use in
these situations, that will correctly convert our string text input into valid numbers. We could
either add a property, or use the converter parameter to specify which type of number we
want to convert to and provide a few alternative conversion methods.
As always with WPF, there are a number of different ways to implement any solution. There
are also several other ways to stop users from entering invalid data; we could build, or

make use of a third-party numeric up/down control, enable users to enter time values using
a custom clock control, or even use combo boxes to restrict the value that users can select
to a set of allowable values.

Amalgamating validation and visuals
Let’s now utilize some of the techniques that we discussed in the previous chapter to design
a visually appealing user interface that highlights validation errors in a novel way, using our
glowing example. We’ll first need to add some more resources to use in this example. Let’s
start by adding two further glow brush resources to the GreenGlow brush resource from the
previous chapter:
<RadialGradientBrush x:Key=“BlueGlow” Center=“0.5,0.848”
GradientOrigin=“0.5,0.818” RadiusX=“-1.424” RadiusY=“-0.622”
RelativeTransform=“{StaticResource GlowTransformGroup}”>
<GradientStop Color=“#CF01C7FF” Offset=“0.168” />
<GradientStop Color=“#4B01C7FF” Offset=“0.478” />
<GradientStop Color=“#1101C7FF” Offset=“1” />
</RadialGradientBrush>
<RadialGradientBrush x:Key=“RedGlow” Center=“0.5,0.848”
GradientOrigin=“0.5,0.818” RadiusX=“-1.424” RadiusY=“-0.622”
RelativeTransform=“{StaticResource GlowTransformGroup}”>
<GradientStop Color=“#CFFF0000” Offset=“0.168” />
<GradientStop Color=“#4BFF0000” Offset=“0.478” />
<GradientStop Color=“#00FF0000” Offset=“1” />
</RadialGradientBrush>
Let’s now see the styles that use these brush resources:
<Style x:Key=“GlowStyle” TargetType=“{x:Type Rectangle}“>
<Setter Property=“SnapsToDevicePixels” Value=“True” />
<Setter Property=“Opacity” Value=“1.0” />
<Setter Property=“StrokeThickness” Value=“0” />
<Setter Property=“RadiusX” Value=“2.5” />
<Setter Property=“RadiusX” Value=“2.5” />
<Setter Property=“IsHitTestVisible” Value=“False” />
<Setter Property=“VerticalAlignment” Value=“Stretch” />
<Setter Property=“HorizontalAlignment” Value=“Stretch” />
<Setter Property=“Fill” Value=“{StaticResource BlueGlow}” />
</Style>
This first style is reusable and can be declared in the global application resources, while the
following styles extend it, are data model specific and could be declared locally in our
ProductView class:
<Style x:Key=“ProductGlowStyle” TargetType=“{x:Type Rectangle}”
BasedOn=“{StaticResource GlowStyle}”>
<Style.Triggers>
<DataTrigger Binding=“{Binding Products.CurrentItem.HasChanges,
FallbackValue=False, Mode=OneWay}” Value=“True”>
<Setter Property=“Fill” Value=“{StaticResource GreenGlow}” />
</DataTrigger>
<DataTrigger Binding=“{Binding Products.CurrentItem.HasErrors,
FallbackValue=False, Mode=OneWay}” Value=“True”>
<Setter Property=“Fill” Value=“{StaticResource RedGlow}” />
</DataTrigger>
</Style.Triggers>
</Style>
<Style x:Key=“ProductItemGlowStyle” TargetType=“{x:Type Rectangle}”
BasedOn=“{StaticResource GlowStyle}”>
<Style.Triggers>

<DataTrigger Binding=“{Binding HasChanges, FallbackValue=False,
Mode=OneWay}” Value=“True”>
<Setter Property=“Fill” Value=“{StaticResource GreenGlow}” />
</DataTrigger>
<DataTrigger Binding=“{Binding HasErrors, FallbackValue=False,
Mode=OneWay}” Value=“True”>
<Setter Property=“Fill” Value=“{StaticResource RedGlow}” />
</DataTrigger>
</Style.Triggers>
</Style>
We declare the ProductGlowStyle style for our form rectangle, and the
ProductItemGlowStyle style for our data items in the Products collection. The only
differences can be found in the binding paths of the two data triggers.
In these styles, we add a DataTrigger element that sets the rectangle Fill property to the
GreenGlow resource when the HasChanges property of the current item in the Products
collection is true and another that sets it to the RedGlow resource when the HasErrors
property of the current item is true.
As the trigger that highlights errors is declared after the other one, it will override it if both
conditions are true, which is essential for this example. Let’s now see the Product class
data template resource that makes use of this rectangle style:
xmlns:DataModels=“clr-
namespace:CompanyName.ApplicationName.DataModels;
assembly=CompanyName.ApplicationName.DataModels”
xmlns:Views=“clr-namespace:CompanyName.ApplicationName.Views”
<DataTemplate DataType=“{x:Type DataModels:Product}“>
<Border CornerRadius=“3” BorderBrush=“{StaticResource
TransparentBlack}”
BorderThickness=“1” Background=“{StaticResource
TransparentWhite}“>
<Border Name=“InnerBorder” CornerRadius=“2” Margin=“1”
Background=“{StaticResource LayeredButtonBackground}”>
<Grid>
<Rectangle IsHitTestVisible=“False” RadiusX=“2” RadiusY=“2”
Style=“{StaticResource ProductItemGlowStyle}” />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=“Auto” />
<ColumnDefinition />
<ColumnDefinition Width=“Auto” />
</Grid.ColumnDefinitions>
<Image Width=“24” Height=“24”
Source=“pack://application:,,,/CompanyName.ApplicationName;
component/Images/Product.ico”
VerticalAlignment=“Center”
Margin=“3,2,5,2” />
<TextBlock Grid.Column=“1” HorizontalAlignment=“Left”
VerticalAlignment=“Center” Text=“{Binding Name}”
TextWrapping=“Wrap” Margin=“0,1,5,3” Foreground=“White”
FontSize=“14” />
<Button Grid.Column=“2”

Command=“{Binding DataContext.DeleteCommand,
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type Views:ProductView}}}”
CommandParameter=“{Binding}” Margin=“0,2,4,2”
Width=“20” Height=“20”>
<Image Width=“16” Height=“16”
Source=“pack://application:,,,/CompanyName.ApplicationName;
component/Images/Delete_16.png”
HorizontalAlignment=“Center”
VerticalAlignment=“Center” />
</Button>
</Grid>
</Grid>
</Border>
</Border>
</DataTemplate>
In this example, we reuse our double border technique from the previous chapter, so there’s
no need to examine that code again. Inside the borders, we declare a Grid panel that
contains a rectangle that has our new ProductItemGlowStyle style applied to it and another
Grid panel to display each user’s name and a couple of images.
These images are from the Visual Studio 2015 icon set and the first signifies that these
objects are products. The VerticalAlignment property of each of the three elements is set
to Center to ensure that they are all aligned vertically and the TextWrapping property of the
TextBlock element is set to Wrap in case any products have a long name.
The second image specifies that each of these items can be deleted. Note that it is
declared within a Button control and while we have not attempted to style that button, it
could also be given the double border treatment, or any other custom style. This button is
optional, but has been included merely as an example of linking a command from the View
Model to each data object.
Note that the binding path in the button’s Command property uses a RelativeSource binding
to reference the ancestor of type ProductView. In particular, it references the
DeleteCommand property of the DataContext of the View, which in our case, is an instance of
our ProductViewModel class.
The CommandParameter property is then data bound to the whole data context of each data
template, which means that the whole data model object will be passed through as the
command parameter. Using our ActionCommand class, this is specified by the action and
canExecute fields in the following example, which should be added to the
ProductViewModel, along with the related methods:
using System.Windows.Input;
using CompanyName.ApplicationName.ViewModels.Commands;
public ICommand DeleteCommand
{
get { return new ActionCommand(action => Delete(action),
canExecute => CanDelete(canExecute)); }

}
private bool CanDelete(object parameter)
{
return Products.Contains((Product)parameter);
}
private void Delete(object parameter)
{
Products.Remove((Product)parameter);
}
In this example, our CanDelete method simply returns true if the command parameter
product is contained in the Products collection, but this can be replaced with your own
condition. For example, you could check whether the item has any changes, or whether the
current user has the correct security permission to delete objects. Our Delete method
simply removes the cast Product input parameter from the Products collection.
Now that we have styled our Product items in the ListBox with this data template, there is
something else that we can do to improve the look further; we can remove the default
selection rectangle of the ListBoxItem elements that wrap our data models. In .NET 3.5
and before, we could simply add some resources into a style for the ListBoxItem class that
would do the job for us:
<Style TargetType=“{x:Type ListBoxItem}“>
<Style.Resources>
<SolidColorBrush x:Key=“{x:Static
SystemColors.HighlightBrushKey}”
Color=“Transparent” />
<SolidColorBrush x:Key=“{x:Static
SystemColors.ControlBrushKey}”
Color=“Transparent” />
<SolidColorBrush x:Key=“{x:Static
SystemColors.HighlightTextBrushKey}”
Color=“Black” />
<SolidColorBrush x:Key=“{x:Static
SystemColors.ControlTextBrushKey}”
Color=“Black” />
</Style.Resources>
</Style>
However, from .NET 4.0 onwards, this will no longer work. Instead, we now need to define
a new ControlTemplate object for the ListBoxItem class that does not highlight its
background when selected, or when the user’s mouse cursor is over it.
<Style TargetType=“{x:Type ListBoxItem}“>
<Setter Property=“Padding” Value=“0” />
<Setter Property=“Margin” Value=“2,2,2,0” />
<Setter Property=“BorderThickness” Value=“1” />
<Setter Property=“Template”>
<Setter.Value>
<ControlTemplate TargetType=“{x:Type ListBoxItem}“>
<Border x:Name=“Bd” BorderBrush=“{TemplateBinding
BorderBrush}”
BorderThickness=“{TemplateBinding BorderThickness}”
Background=“{TemplateBinding Background}”

Padding=“{TemplateBinding Padding}”
SnapsToDevicePixels=“True”>
<ContentPresenter
ContentTemplate=“{TemplateBinding ContentTemplate}”
Content=“{TemplateBinding Content}”
ContentStringFormat=“{TemplateBinding
ContentStringFormat}”
HorizontalAlignment=“{TemplateBinding
HorizontalContentAlignment}”
SnapsToDevicePixels=“{TemplateBinding
SnapsToDevicePixels}”
VerticalAlignment=“{TemplateBinding
VerticalContentAlignment}”
/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property=“IsEnabled” Value=“False”>
<Setter Property=“TextElement.Foreground”
TargetName=“Bd” Value=“{DynamicResource
{x:Static SystemColors.GrayTextBrushKey}}” />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
To create the ControlTemplate element in this style, we first accessed the default template
of the ListBoxItem class, as described in the Modifying Existing Controls section of
Chapter 5, Using the Right Controls for the Job, and then simply removed the triggers that
colored the background. We then added it to a style with no x :Key directive, so that it will
be implicitly applied to all ListBoxItem elements within scope.
Next, we have the ErrorBorderStyle style that styles the border of our global validation
error display and uses our BoolToVisibilityConverter class to set the Visibility
property to show the control when the HasErrors property of the current item in the
Products collection is true:
<Style x:Key=“ErrorBorderStyle” TargetType=“{x:Type Border}“>
<Setter Property=“BorderBrush” Value=“#7BFF0000” />
<Setter Property=“Background” Value=“#FFFFDFE1” />
<Setter Property=“BorderThickness” Value=“1” />
<Setter Property=“CornerRadius” Value=“2.75” />
<Setter Property=“Padding” Value=“5,3” />
<Setter Property=“Margin” Value=“0,0,0,5” />
<Setter Property=“SnapsToDevicePixels” Value=“True” />
<Setter Property=“Visibility”
Value=“{Binding Products.CurrentItem.HasErrors,
Converter={StaticResource BoolToVisibilityConverter},
FallbackValue=Collapsed, Mode=OneWay}” />
</Style>
For this example, we want the ability to know when the data has changed, so we’ll also
need to update our BaseNotifyValidationModel class to extend our earlier
BaseSynchronizableDataModel class. In order to do that, we’ll need to make it generic and
add the same generic constraints for the T generic type parameter to its declaration:

public abstract class BaseNotifyValidationModel<T> :
BaseSynchronizableDataModel<T>,
INotifyPropertyChanged, INotifyDataErrorInfo
where T : BaseDataModel, ISynchronizableDataModel<T>, new()
We’ll need to remove its default implementation of the INotifyPropertyChanged interface
and make use of the existing implementation from the BaseSynchronizableDataModel class.
We’ll also need to implement the base class’ required members in our Product class:
public class Product : BaseNotifyValidationModel<Product>
{
public override void CopyValuesFrom(Product product)
{
Id = product.Id;
Name = product.Name;
Price = product.Price;
}
public override bool PropertiesEqual(Product otherProduct)
{
if (otherProduct == null) return false;
return Id == otherProduct.Id && Name == otherProduct.Name &&
Price == otherProduct.Price;
}
}
The CopyValuesFrom method is used by the base class to make cloned copies of the data
object and the PropertiesEqual method is used to compare its property values with other
Product instances.
Now that we have updated our BaseNotifyValidationModel class to extend our earlier
BaseSynchronizableDataModel class and extended this in our Product class, we can now
update the Products class to extend our earlier BaseSynchronizableCollection class:
public class Products : BaseSynchronizableCollection<Product> { }
With our new Products collection, we can now call the Synchronize method in the
constructor of the ProductViewModel class, after adding the two products to it:
Products.Synchronize();
Now that we’ve updated the ProductViewModel class, let’s see move onto the ProductView
class:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ListBox ItemsSource=“{Binding Products}”
SelectedItem=“{Binding Products.CurrentItem}” Margin=“0,0,20,0”
HorizontalContentAlignment=“Stretch” />
<Border Grid.Column=“1” CornerRadius=“3”
BorderBrush=“{StaticResource TransparentBlack}”
BorderThickness=“1”
Background=“{StaticResource TransparentWhite}”>

<Border Name=“InnerBorder” CornerRadius=“2” Margin=“1”
Background=“{StaticResource LayeredButtonBackground}”>
<Grid>
<Rectangle IsHitTestVisible=“False” RadiusX=“2” RadiusY=“2”
Style=“{StaticResource ProductGlowStyle}” />
<Grid Margin=“10”>
<Grid.RowDefinitions>
<RowDefinition Height=“Auto” />
<RowDefinition Height=“Auto” />
<RowDefinition Height=“Auto” />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=“Auto” />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Border Grid.ColumnSpan=“2” Style=“{StaticResource
ErrorBorderStyle}” Margin=“0,0,0,10” Padding=“10”>
<ItemsControl
ItemsSource=“{Binding Products.CurrentItem.Errors}”
ItemTemplate=“{StaticResource WrapTemplate}” />
</Border>
<TextBlock Grid.Row=“1” Text=“Name”
Style=“{StaticResource LabelStyle}” />
<TextBox Grid.Row=“1” Grid.Column=“1”
Text=“{Binding Products.CurrentItem.Name,
UpdateSourceTrigger=PropertyChanged}”
Style=“{StaticResource TextBoxStyle}” />
<TextBlock Grid.Row=“2” Text=“Price”
Style=“{StaticResource LabelStyle}” />
<TextBox Grid.Row=“2” Grid.Column=“1”
Text=“{Binding Products.CurrentItem.Price
UpdateSourceTrigger=PropertyChanged}”
Style=“{StaticResource TextBoxStyle}”
Attached:TextBoxProperties.IsNumericOnly =“True” />
</Grid>
</Grid>
</Border>
</Border>
</Grid>
We have the same Grid panel, with a ListBox control on the left and some form controls on
the right. Note that we set the HorizontalContentAlignment property to Stretch on the
ListBox control to ensure that its ListBoxItem elements stretch to fit its whole width.
On the right, we then see the double borders and the rectangle that is painted with the glow
color resource that we created in the previous chapter. Rather than hardcoding one
particular color resource as we did earlier, we instead apply our new ProductGlowStyle
style to it, that will change the color with its data triggers.
Note that we have added an outer Grid panel that only contains the glow rectangle and the
original G rid panel, which now adds an outer margin to our form. The original panel
remains much unchanged, although the error display border now uses our new
ErrorBorderStyle style.
The form fields also remain unchanged, although when using our extended implementation,
we no longer need to set the ValidatesOnNotifyDataErrors property to true on each

binding. We also updated the LabelStyle style to add a setter to color the label foreground
white and edited the TextBoxStyle style to add a setter to set the
Validation.ErrorTemplate Attached Property to x:Null to hide the default red error
border when there are validation errors.
When running this View now, it would render the following visual output, with a red glow on
the form and the item in error:
After correcting the errors, we’ll see a green glow on the form and the edited item:
After saving the changes, we’d need to call the Synchronize method on the Products
collection again and then we’d see this, where all objects are now painted with the blue
glow:

Summary
In this chapter, we had a thorough look at the data validation options that the .NET
Framework offers us, primarily concentrating on a variety of ways to implement the two
available validation interfaces. We investigated the use of the data annotation validation
attributes, explored providing custom error templates and aggregated our new found
knowledge with that from the previous chapter to build up a visually pleasing validation
example.
In the next chapter, we’ll look a number of ways that we can provide users of our
applications with a great user experience, from asynchronous programming to feedback
mechanisms. We will also examine how to make use of application settings to provide user
preferences and examine a variety of ways of supplying in-application help to the
application users. We will end with a further look into additional ways of improving the user
experience for the end users.

Chapter 9. Completing That Great User
Experience
As we have seen, it is easy to add form fields to a View and produce visually appealing and
functionally adequate applications. However, it can take a lot more work to provide the end
user with an interface that truly ticks all of the boxes. For example, how many times have
you clicked on a button in an application and had the whole application freeze while it does
some work?
In this chapter, we’ll look into solving this problem by using asynchronous programming,
along with a number of other ways of improving the user experience of the end user. For
example, we’ll investigate enabling the users to customize their versions of the application
using their own user preference settings.
We’ll discuss keeping the users informed, by providing user feedback and update our
application framework by adding a feedback system. We’ll explore a few alternative
methods of providing in-application help files and/or documentation and a number of other
ways of making the application more user friendly and the life of the users that much easier.
Providing user feedback
One essential facet of a great application is keeping the end users up to date with what’s
going on in the application. If they click on a function button, they should be informed as to
the progress and/or the status of the operation. Without adequate feedback, the user can
be left wondering whether a particular operation worked and may attempt to run it several
times, possibly causing errors.
It is therefore essential to implement a feedback system into our application framework. So
far in this book, we’ve seen the name of the FeedbackManager class in a few places,
although we’ve seen very little implementation. Let’s now see how we can implement a
working feedback system in our application framework, starting with the Feedback class
that holds the individual feedback messages:
using System;
using System.ComponentModel;
using CompanyName.ApplicationName.DataModels.Enums;
using CompanyName.ApplicationName.DataModels.Interfaces;
using CompanyName.ApplicationName.Extensions;
namespace CompanyName.ApplicationName.DataModels
{
public class Feedback : IAnimatable, INotifyPropertyChanged
{
private string message = string.Empty;
private FeedbackType type = FeedbackType.None;
private TimeSpan duration = new TimeSpan(0, 0, 4);
private bool isPermanent = false;
private Animatable animatable;
public Feedback(string message, FeedbackType type, TimeSpan
duration)

{
Message = message;
Type = type;
Duration = duration == TimeSpan.Zero ? this.duration :
duration;
IsPermanent = false;
Animatable = new Animatable(this);
}
public Feedback(string message, bool isSuccess, bool
isPermanent) :
this(message, isSuccess ? FeedbackType.Success :
FeedbackType.Error, TimeSpan.Zero)
{
IsPermanent = isPermanent;
}
public Feedback(string message, FeedbackType type) :
this(message,
type, TimeSpan.Zero) { }
public Feedback(string message, bool isSuccess) : this(message,
isSuccess ? FeedbackType.Success : FeedbackType.Error,
TimeSpan.Zero) { }
public Feedback() : this(string.Empty, FeedbackType.None) { }
public string Message
{
get { return message; }
set { message = value; NotifyPropertyChanged(); }
}
public TimeSpan Duration
{
get { return duration; }
set { duration = value; NotifyPropertyChanged(); }
}
public FeedbackType Type
{
get { return type; }
set { type = value; NotifyPropertyChanged(); }
}
public bool IsPermanent
{
get { return isPermanent; }
set { isPermanent = value; NotifyPropertyChanged(); }
}
#region IAnimatable Members
public Animatable Animatable
{
get { return animatable; }
set { animatable = value; }
}

#endregion
#region INotifyPropertyChanged Members
#endregion
}
}
Note that our Feedback class implements the IAnimatable interface that we saw earlier,
along with the INotifyPropertyChanged interface. After declaring the private fields, we
declare a number of useful constructor overloads.
In this example, we have hardcoded a default feedback display duration of four seconds for
the duration field. In the main constructor, we set the Duration property, dependent upon
the value of the duration input parameter; if the input parameter is the TimeSpan.Zero field,
then the default value is used, but if the input parameter is a non-zero value, it will be used.
The Message property will hold the feedback message, the Duration property specifies the
length of time that the message will be displayed, the Type property uses the FeedbackType
enumeration that we saw earlier to specify the type of the message and the IsPermanent
property dictates whether the message should be permanently displayed until the user
manually closes it or not.
The implementation of our IAnimatable class is shown beneath the other properties and
simply consists of the Animatable property, but our implementation of the
INotifyPropertyChanged interface has been omitted for brevity, as we are using the default
implementation that we saw earlier.
Let’s now see the FeedbackCollection class that will contain the individual Feedback
instances:
using System.Collections.Generic;
using System.Linq;
namespace CompanyName.ApplicationName.DataModels.Collections
{
public class FeedbackCollection :
BaseAnimatableCollection<Feedback>
{
public FeedbackCollection(IEnumerable<Feedback>
feedbackCollection) :
base(feedbackCollection) { }
public FeedbackCollection() : base() { }
public new void Add(Feedback feedback)
{
if (!string.IsNullOrEmpty(feedback.Message) && (Count == 0 ||
!this.Any(f => f.Message == feedback.Message)))
base.Add(feedback);
}
public void Add(string message, bool isSuccess)

{
Add(new Feedback(message, isSuccess));
}
}
}
The FeedbackCollection class extends our BaseAnimatableCollection class that we saw
earlier and sets its generic type parameter to the Feedback class. This is a very simple
class and declares a couple of constructors, passing any input parameters straight through
to the base class constructors.
In addition to this, it declares two Add methods, with the second simply creating a Feedback
object from its input parameters and passing it to the first method. The first method first
checks that the feedback message is not null or empty and that an identical message is not
already contained in the feedback collection, before adding the new message to the
collection.
Let’s now look at the FeedbackManager class that uses these two classes internally:
using System.ComponentModel;
using System.Runtime.CompilerServices;
using CompanyName.ApplicationName.DataModels;
using CompanyName.ApplicationName.DataModels.Collections;
namespace CompanyName.ApplicationName.Managers
{
public class FeedbackManager : INotifyPropertyChanged
{
private static FeedbackCollection feedback = new
FeedbackCollection();
private static FeedbackManager instance = null;
private FeedbackManager() { }
public static FeedbackManager Instance =>
instance ?? (instance = new FeedbackManager());
public FeedbackCollection Feedback
{
get { return feedback; }
set { feedback = value; NotifyPropertyChanged(); }
}
public void Add(Feedback feedback)
{
Feedback.Add(feedback);
}
public void Add(string message, bool isSuccess)
{
Add(new Feedback(message, isSuccess));
}
#region INotifyPropertyChanged Members

#endregion
}
}
The FeedbackManager class also implements the INotifyPropertyChanged interface and in
it, we see the static FeedbackCollection field. Next, we see the static instance field, the
private constructor and the static Instance property of type FeedbackManager, that
instantiates the instance field on the first use and tells us that this class follows the
Singleton pattern.
The Feedback property follows and is the class’ access to the FeedbackCollection field.
After that, we see a number of convenient overloads of the Add method that enable
developers to add feedback using different parameters. Our implementation of the
INotifyPropertyChanged interface here has again been omitted for brevity, but it uses our
default implementation that we saw earlier.
Let’s now focus on the XAML of the FeedbackControl object:
<UserControl
x:Class=“CompanyName.ApplicationName.Views.Controls.FeedbackControl
“
compatibility/2006”
xmlns:Controls=“clr-
namespace:CompanyName.ApplicationName.Views.Controls”
xmlns:Converters=“clr-
namespace:CompanyName.ApplicationName.Converters;
assembly=CompanyName.ApplicationName.Converters”
xmlns:DataModels=“clr-
namespace:CompanyName.ApplicationName.DataModels;
assembly=CompanyName.ApplicationName.DataModels”
xmlns:Panels=“clr-
namespace:CompanyName.ApplicationName.Views.Panels”
mc:Ignorable=“d” d:DesignHeight=“22” d:DesignWidth=“300”>
<UserControl.Resources>
<Converters:FeedbackTypeToImageSourceConverter
x:Key=“FeedbackTypeToImageSourceConverter” />
<Converters:BoolToVisibilityConverter
x:Key=“BoolToVisibilityConverter” />
<ItemsPanelTemplate x:Key=“AnimatedPanel”>
<Panels:AnimatedStackPanel />
</ItemsPanelTemplate>
<Style x:Key=“SmallImageInButtonStyle” TargetType=“{x:Type
Image}”
BasedOn=“{StaticResource ImageInButtonStyle}”>
<Setter Property=“Width” Value=“16” />
<Setter Property=“Height” Value=“16” />
</Style>
<DataTemplate x:Key=“FeedbackTemplate” DataType=“{x:Type
DataModels:Feedback}“>
<Grid Margin=“2,1,2,0” MouseEnter=“Border_MouseEnter”
MouseLeave=“Border_MouseLeave”>

<Grid.ColumnDefinitions>
<ColumnDefinition Width=“16” />
<ColumnDefinition />
<ColumnDefinition Width=“24” />
</Grid.ColumnDefinitions>
<Image Stretch=“None” Source=“{Binding Type,
Converter={StaticResource
FeedbackTypeToImageSourceConverter}}”
VerticalAlignment=“Top” Margin=“0,4,0,0” />
<TextBlock Grid.Column=“1” Text=“{Binding Message}”
MinHeight=“22” TextWrapping=“Wrap” Margin=“5,2,5,0”
VerticalAlignment=“Top” FontSize=“14” />
<Button Grid.Column=“2” ToolTip=“Removes this message from
the
list” VerticalAlignment=“Top” PreviewMouseLeftButtonDown=
“DeleteButton_PreviewMouseLeftButtonDown”>
<Image Source=“pack://application:,,,/
CompanyName.ApplicationName;component/Images/Delete_16.png”
Style=“{StaticResource SmallImageInButtonStyle}” />
</Button>
</Grid>
</DataTemplate>
<DropShadowEffect x:Key=“Shadow” Color=“Black” ShadowDepth=“6”
Direction=“270” Opacity=“0.4” />
</UserControl.Resources>
<Border BorderBrush=“{StaticResource TransparentBlack}”
Background=“White” Padding=“3” BorderThickness=“1,0,1,1”
CornerRadius=“0,0,5,5” Visibility=“{Binding HasFeedback,
Converter={StaticResource BoolToVisibilityConverter},
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type Controls:FeedbackControl}}}”
Effect=“{StaticResource Shadow}”>
<ListBox MaxHeight=“89” ItemsSource=“{Binding Feedback,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type Controls:FeedbackControl}}}”
ItemTemplate=“{StaticResource FeedbackTemplate}”
ItemsPanel=“{StaticResource AnimatedPanel}”
ScrollViewer.HorizontalScrollBarVisibility=“Disabled”
ScrollViewer.VerticalScrollBarVisibility=“Auto”
BorderThickness=“0”
HorizontalContentAlignment=“Stretch” />
</Border>
</UserControl>
We start by adding a number of XML namespace prefixes for some of our application
projects. Using the Converters prefix, we add instances of the
FeedbackTypeToImageSourceConverter and BoolToVisibilityConverter classes that we
saw earlier into the UserControl.Resources section. We also reuse our
AnimatedStackPanel class from Chapter 6, Mastering Practical Animations.
Next, we see the SmallImageInButtonStyle style, that is based on the ImageInButtonStyle
style that we also saw earlier, and adds some sizing properties. After that, we see the
FeedbackStyle style that defines what each feedback message will look like in our
feedback control.

Each Feedback object will be rendered in three columns; the first contains an image that
specifies the type of feedback, using the FeedbackTypeToImageSourceConverter class that
we saw earlier, the second displays the message, with a TextWrapping value of Wrap, and
the third holds a button with an image, using our SmallImageInButtonStyle style, that users
can use to remove the message.
Note that, as this is purely a UI control with no business logic in, we are able to use the
code behind file, even when using MVVM. As such, we attach event handlers for the
MouseEnter and MouseLeave events to the Grid panel containing each Feedback object and
another for the PreviewMouseLeftButtonDown event to the delete button. The final resource
that we have here is a DropShadowEffect instance that defines a small shadow effect.
For the feedback control, we define a Border element that uses a semi-transparent border
brush and has a BorderThickness value of 1,0,1,1 and a CornerRadius value of 0,0,5,5.
These four values work like the Margin property and enable us to set different values for
each of the four sides, or corners in the case of the CornerRadius property. In this way, we
can display a rectangle that is only bordered on three sides, with rounded corners on two.
Note that the Visibility property on this border is determined by the HasFeedback
property of the FeedbackControl class via an instance of our BoolToVisibilityConverter
class. Therefore, when there are no feedback objects to display, the border will be hidden.
Also note that our Shadow resource is applied to the border’s Effect property.
Inside the border, we declare a ListBox control, with its ItemsSource property set to the
Feedback property of the FeedbackControl class and its height restricted to a maximum of
three feedback items, after which, vertical scrollbars will be shown. Its ItemTemplate
property is set to the FeedbackTemplate that we defined in the resources section.
Its ItemsPanel property is set to the AnimatedPanel resource that we declared to animate
the entrance and exit of the feedback items. Next, we remove the default border of the
ListBox by setting the BorderThickness property to 0 and stretch the autogenerated
ListBoxItem objects to fit the width of the ListBox control by setting the
HorizontalContentAlignment property to Stretch.
Let’s now see the code behind of our feedback control:
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Threading;
using CompanyName.ApplicationName.DataModels;
using CompanyName.ApplicationName.DataModels.Collections;
using CompanyName.ApplicationName.Extensions;
namespace CompanyName.ApplicationName.Views.Controls
{
public partial class FeedbackControl : UserControl
{
private static List<DispatcherTimer> timers =
new List<DispatcherTimer>();

public FeedbackControl()
{
InitializeComponent();
}
public static readonly DependencyProperty FeedbackProperty =
DependencyProperty.Register(nameof(Feedback),
typeof(FeedbackCollection), typeof(FeedbackControl),
new UIPropertyMetadata(new FeedbackCollection(),
(d, e) => ((FeedbackCollection)e.NewValue).CollectionChanged
+=
((FeedbackControl)d).Feedback_CollectionChanged));
public FeedbackCollection Feedback
{
get { return (FeedbackCollection)GetValue(FeedbackProperty);
}
set { SetValue(FeedbackProperty, value); }
}
public static readonly DependencyProperty HasFeedbackProperty =
DependencyProperty.Register(nameof(HasFeedback),
typeof(bool),
typeof(FeedbackControl), new PropertyMetadata(true));
public bool HasFeedback
{
get { return (bool)GetValue(HasFeedbackProperty); }
set { SetValue(HasFeedbackProperty, value); }
}
private void Feedback_CollectionChanged(object sender,
NotifyCollectionChangedEventArgs e)
{
if ((e.OldItems == null || e.OldItems.Count == 0) &&
e.NewItems != null && e.NewItems.Count > 0)
{
e.NewItems.OfType<Feedback>().Where(f => !f.IsPermanent).
ForEach(f => InitializeTimer(f));
}
HasFeedback = Feedback.Any();
}
private void InitializeTimer(Feedback feedback)
{
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = feedback.Duration;
timer.Tick += Timer_Tick;
timer.Tag = new Tuple<Feedback, DateTime>(feedback,
DateTime.Now);
timer.Start();
timers.Add(timer);
}
private void Timer_Tick(object sender, EventArgs e)
{
DispatcherTimer timer = (DispatcherTimer)sender;

timer.Stop();
timer.Tick -= Timer_Tick;
timers.Remove(timer);
Feedback feedback = ((Tuple<Feedback,
DateTime>)timer.Tag).Item1;
Feedback.Remove(feedback);
}
private void DeleteButton_PreviewMouseLeftButtonDown(object
sender,
MouseButtonEventArgs e)
{
Button deleteButton = (Button)sender;
Feedback feedback = (Feedback)deleteButton.DataContext;
Feedback.Remove(feedback);
}
private void Border_MouseEnter(object sender, MouseEventArgs e)
{
foreach (DispatcherTimer timer in timers)
{
timer.Stop();
Tuple<Feedback, DateTime> tag =
(Tuple<Feedback, DateTime>)timer.Tag;
tag.Item1.Duration = timer.Interval = tag.Item1.Duration.
Subtract(DateTime.Now.Subtract(tag.Item2));
}
}
private void Border_MouseLeave(object sender, MouseEventArgs e)
{
foreach (DispatcherTimer timer in timers)
{
Feedback feedback = ((Tuple<Feedback,
DateTime>)timer.Tag).Item1;
timer.Tag = new Tuple<Feedback, DateTime>(feedback,
DateTime.Now);
timer.Start();
}
}
}
}
We start by declaring the collection of DispatcherTimer instances that will be responsible
for timing when each feedback object should be removed from the collection, according to
its Duration property. We then see the declaration of the Feedback and HasFeedback
Dependency Properties, along with their CLR wrappers and the Feedback property’s
CollectionChanged handler.
In the attached Feedback_CollectionChanged handler method, we call the InitializeTimer
method, passing in each new, non-permanent feedback item. Note that we need to use the
OfType LINQ Extension method to cast each item in the NewItems property of the
NotifyCollectionChangedEventArgs class from the object type to Feedback. Before
returning control to the caller, we set the HasFeedback property accordingly.

In the InitializeTimer method, we initialize a DispatcherTimer instance and set its interval
to the value from the Duration property of the feedback input parameter. We then attach
the Timer_Tick event handler, add the current time and the feedback object into the Tag
property of the timer for later use, start the timer and add it into the timers collection.
In the Timer_Tick method, we access the timer from the sender input parameter and the
Feedback instance from its Tag property. The feedback item is then removed from the
Feedback collection, the timer is stopped and removed from the timers collection and the
Tick event handler is detached.
In the DeleteButton_PreviewMouseLeftButtonDown method, we first cast the delete button
from the sender input parameter. We then cast the Feedback object from the button’s
DataContext property and remove it from the Feedback collection.
In the Border_MouseEnter method, we iterate through the timers collection and stop each
timer. The interval of each timer and duration of each associated Feedback object is then
set to the remaining time that they should be displayed for, in effect, pausing their durations.
Finally, we see the Border_MouseLeave method, which re-initializes the Tag property of each
timer in the timers collection, with the same feedback item and the current date and time,
and restarts it when the user’s mouse pointer leaves the feedback control.
This means that the length of time that temporary feedback messages are displayed for
can be extended if the user moves their mouse pointer over the feedback control. This
feature will hold the feedback messages in the control for as long as the user keeps their
mouse pointer over the control, giving them ample time to read the messages. Let’s now
see what this control looks like:
If you have menu buttons at the top of your Views, then you could alternatively have the
feedback appear at the bottom of the application, or even sliding in from one of the sides.
Also note that the delete buttons have not been styled, so as to shorten this example, but
they should be styled in line with the other controls in a real application.
If you remember from Chapter 3, Writing Custom Application Frameworks, all of our View
Models will have access to our new FeedbackManager class through the FeedbackManager
property in our BaseViewModel class, and so we can replicate the feedback in the preceding
image from any View Model like this:
FeedbackManager.Add(new Feedback(“Here’s some information for you”,
FeedbackType.Information));

FeedbackManager.Add(“Something was saved successfully”, true);
FeedbackManager.Add(“Something else went wrong”, false);
FeedbackManager.Add(“Something else went wrong too”, false);

Utilizing multiple threads
Traditionally, all applications were developed as single threaded applications. However,
when long running background processes were running, the application UI would freeze and
become unresponsive, because the single thread was busy elsewhere. This problem and
other performance bottlenecks led to the current era of asynchronous programming and
multi-threaded applications.
In days gone by, creating multi-threaded applications was a complicated matter. With each
successive version of the .NET Framework, Microsoft have striven to make this task easier.
Originally, we only had the Thread class and then the BackgroundWorker class in .NET 2.0,
but in .NET 4.0, they introduced the Task class and in .NET 4.5, they introduced the async
and await keywords.
In this section, we will explore the latter methods of multithreading and add functionality to
our application framework that will enable us to perform our data retrieval and update
actions asynchronously. Let’s start by looking at the async and await keywords first.
Discovering the Async and Await keywords
Along with these new keywords, Microsoft have also added a plethora of new methods
across the .NET Framework that end with the suffix Async. As the suffix hints, these new
methods are all asynchronous and can be used in conjunction with the new keywords. Let’s
start with the basic rules.
First of all, in order to use the await keyword in a method, the method signature must be
declared with the async keyword. The async keyword enables us to use the await keyword
in the method and returns just the T generic type parameter from a method that actually
returns the Task<T> type. A method that is modified with the async keyword is known as an
async method.
Async methods actually execute in a synchronous manner, until they reach an await
expression. If there is no await keyword in the method, then the whole method will run
synchronously and the compiler will output a warning.
While a portion of async methods run asynchronously, they don’t in fact run on their own
threads. No additional threads are created using the async and await keywords. Instead,
they give the appearance of multithreading by using the current synchronization context, but
only when the method is active and not when it is paused while running an await
expression.
When execution reaches an await keyword, the method is suspended until the awaited task
has completed asynchronously. During this time, execution returns to the method caller.
When the asynchronous action is complete, program execution returns to the method and
the remainder of the code in it is run synchronously.
Async methods are required to have a particular signature. They all need to use the async
modifier keyword and in addition to this, the names of async methods should end with the
Async suffix to clearly signify that they are asynchronous methods. Another requirement of
declaring async methods is that they cannot contain any ref or out input parameters.
The final requirement is that async methods can only use one of three return types; Task,

the generic Task<TResult>, or void. Note that the generic TResult type parameter is the
same as and can be replaced with T, but Microsoft refer to it as TResult simply because it
specifies a return type.
All async methods that return some meaningful result will use the Task<TResult> type,
where the actual type of the return value will be specified by the TResult generic type
parameter. Therefore, if we want to return a string from our async method, we would
declare that our async method returns a parameter of type Task<string>. Let’s see an
example of this in action:
using System;
using System.IO;
using System.Threading.Tasks;
public async Task<string> GetTextFileContentsAsync(string filePath)
{
string fileContents = string.Empty;
try
{
using (StreamReader streamReader = File.OpenText(filePath))
{
fileContents = await streamReader.ReadToEndAsync();
}
}
catch { /Log error/ }
return fileContents;
}
Here we have a simple async method that returns a string that represents the contents of
the text file specified by the filePath input parameter. Note that the actual return type of
the method is in fact Task<string>. In it, we first initialize the fileContents variable and
then attempt to create a StreamReader instance from the File.OpenText method within the
using statement.
Inside the using statement, we attempt to populate the fileContents variable by awaiting
the result of the ReadToEndAsync method of the StreamReader class. Up until this point, the
method will run synchronously. The ReadToEndAsync method will be called and then control
will immediately return to the caller of our async method.
When the return value of the ReadToEndAsync method is ready, control returns to our async
method and continues where it left off. In our example, there is nothing else to do but return
the result string, although async methods can contain any number of lines after the await
keyword, or even multiple await keywords. Note that in a real-world application, we would
log any exceptions that might be thrown from this method.
If our async method just performs some function asynchronously, but does not return
anything, then we use a return type of Task. That is, the task-based async method will
return a Task object that enables it to be used with the await keyword, but the actual
method will not return anything to the caller of that method. Let’s see an example of this:
using System.Text;

public async Task SetTextFileContentsAsync(string filePath,
string contents)
{
try
{
byte[] encodedFileContents =
Encoding.Unicode.GetBytes(contents);
using (FileStream fileStream = new FileStream(filePath,
FileMode.OpenOrCreate, FileAccess.Write, FileShare.None,
4096, true))
{
await fileStream.WriteAsync(encodedFileContents, 0,
encodedFileContents.Length);
}
}
catch { /Log error/ }
}
In the SetTextFileContentsAsync method, we first need to convert our input string to a
byte array. For this reason, we now need to add a using directive for the System.Text
namespace in addition to the three originally specified. Note that in this particular example,
we are using Unicode encoding, but you are free to use any other encoding value here.
After using the GetBytes method to obtain a byte array from the contents input parameter,
we initialize a new FileStream object within another using statement. Apart from the bool
useAsync input parameter, the remaining parameters used in the FileStream constructor in
this example are unimportant and you are free to replace them with values that suit your
requirements better.
Inside the using statement, we see the await keyword used with the WriteAsync method.
Up until this point, this method will run synchronously and on this line, it will start execution
of the WriteAsync method and then return control to the method caller.
As execution leaves the using statement, the FileStream instance will be closed and
disposed of. As this method has nothing to return, the return type of the async method is
Task, which enables it to be awaited by the calling code. Again, we would typically log any
exceptions that might be thrown from this method, but this is omitted here for brevity.
Most of us will never use the third return type option of void when using MVVM, because it
is primarily used in event handling methods. Note that async methods that return void
cannot be awaited and that calling code cannot catch exceptions thrown from such async
methods.
One of the most commonly asked questions regarding async methods is “How can I create
an async method from a synchronous method?” Luckily, there is a very simple solution to
this using the Task.Run method, so let’s take a quick look at it now.
await Task.Run(() => SynchronousMethod(parameter1, parameter2,
etc));
Here we use a Lambda expression to specify the synchronous method to run in an
asynchronous context. That’s all that we have to do to run a synchronous method
asynchronously. However, what about the opposite requirement? Let’s now see how we can

run an asynchronous method synchronously. Again, the Task class provides us with a
solution:
Task task = SetFileContentsAsync(filePath, contents);
task.RunSynchronously();
As we saw at the end of Chapter 1, A Smarter Way of Working with WPF, in order to run
an asynchronous method synchronously, we first need to instantiate a Task instance from
our asynchronous method. Then, all we have to do is call the RunSynchronously method on
that instance and it will run synchronously.
Building asynchrony into our framework
Using the Task class, we can add functionality into our application framework that will
enable us to call any data access method asynchronously. Furthermore, it will also enable
us to run our data operations asynchronously when the application is running and
synchronously while testing. In order to achieve this, we will need to implement several
parts, that go together to provide this functionality.
Let’s look at the first part, that will wrap each data operation and hold the result value, if
applicable, along with any feedback messages and/or error details.
using System;
using System.Data.SqlClient;
using CompanyName.ApplicationName.DataModels.Enums;
using CompanyName.ApplicationName.Extensions;
namespace CompanyName.ApplicationName.DataModels
{
public abstract class DataOperationResult<T>
{
public DataOperationResult(string successText)
{
Description = string.IsNullOrEmpty(successText) ?
“The data operation was successful” : successText;
}
public DataOperationResult(Exception exception, string
errorText)
{
Exception = exception;
if (Exception is SqlException)
{
if (exception.Message.Contains(“The server was not found”))
Error = DataOperationError.DatabaseConnectionError;
else if (exception.Message.Contains(“constraint”))
Error = DataOperationError.DatabaseConstraintError;
// else Description = Exception.Message;
}
if (Error != DataOperationError.None)
Description = Error.GetDescription();
else
{
Error = DataOperationError.UndeterminedDataOperationError;
Description = string.IsNullOrEmpty(errorText) ?
Error.GetDescription() : errorText;
}

}
public DataOperationResult(Exception exception) :
this(exception, string.Empty) { }
public string Description { get; set; }
public DataOperationError Error { get; set; } =
DataOperationError.None;
public Exception Exception { get; set; } = null;
public bool IsSuccess =>
Error == DataOperationError.None && Exception == null;
}
}
In our abstract DataOperationResult class, we have a number of properties and
constructor overloads. The first constructor is used for a successful set data operation and
merely takes the successText input parameter, which is used to populate the Description
property, unless it is null or empty, in which case a default successful operation message is
used instead.
The second constructor is to be used when an exception has been thrown during the data
operation and takes the exception and an error message as input parameters. In it, we first
set the Exception property to the exception specified by the exception input parameter and
then, we have a chance to catch common exceptions and replace their error messages with
custom messages in plain English.
Although we are only checking for exceptions of type SqlException in this example, we
could easily extend this to capture other well-known and/or expected exceptions and
replace their messages with custom messages using laymen terms, by adding further else
…if conditions.
Note that the Error property of enumeration type DataOperationError is used here to set
and output the predefined error messages and we’ll see that in a moment. If the exception
is not one that we were expecting, then we could chose to output the actual exception
message, although that would mean little to the users and could be deemed confusing, or
even worrying.
Instead, we could log the exception in the database and output the message from the
errorText input parameter. We check whether the Error property has been set and if it
has, we call our GetDescription Extension method to retrieve the message that relates to
the set enumeration member and set it to the Description property.
Otherwise, we set the Error property to the UndeterminedDataOperationError member
and the Description property to the value of the errorText input parameter if is not null or
empty, or the text associated with the selected enumeration member if it is. The third
constructor is also used when an exception has been thrown, but when there is no
predefined feedback message.
After the constructors, we see the properties of the DataOperationResult class, most of
which are self-explanatory. Of particular note is the IsSuccess property, which can be used
by the calling code to determine what to do with the result. Let’s now take a look at the

DataOperationError enumeration class that is used to hold the error descriptions:
using System.ComponentModel;
namespace CompanyName.ApplicationName.DataModels.Enums
{
public enum DataOperationError
{
[Description(“”)]
None = 0,
[Description(“A database constraint has not been adhered to, so
this
operation cannot be completed”)]
DatabaseConstraintError = 9995,
[Description(“There was an undetermined data operation error”)]
UndeterminedDataOperationError = 9997,
[Description(“There was a problem connecting to the database”)]
DatabaseConnectionError = 9998,
}
}
As you can see, we utilize the Description Attribute class to relate a humanized error
message with each enumeration member. We can use the GetDescription Extension
method that we saw earlier to access the text values from the attributes.
Each enumeration member is assigned a number and this could work well with the SQL
Server error numbers, if you were using SQL stored procedures or queries directly. For
example, we could cast the SQL error code to the particular enumeration member to get
the custom message for each error. Let’s now take a look at the two classes that extend
the DataOperationResult class:
using System;
namespace CompanyName.ApplicationName.DataModels
{
public class GetDataOperationResult<T> : DataOperationResult<T>
{
public GetDataOperationResult(Exception exception, string
errorText) :
base(exception, errorText)
{
ReturnValue = default(T);
}
public GetDataOperationResult(Exception exception) :
this(exception, string.Empty) { }
public GetDataOperationResult(T returnValue, string
successText) :
base(successText)
{
ReturnValue = returnValue;
}
public GetDataOperationResult(T returnValue) :
this(returnValue, string.Empty) { }

public T ReturnValue { get; private set; }
}
}
We start with the GetDataOperationResult class, which is used to return the result of get
data operations, or the exception details, if an error occurred. It adds a ReturnValue
property of generic type T to hold the return value of the data operation. Apart from this
single member, it simply adds a number of constructors that each call the base class
constructors.
The first is used when an exception has been thrown and sets the ReturnValue property to
its default value, rather than leaving it as null. The second constructor is also used when an
exception has been thrown, but when there is no predefined error message.
The third constructor is used for a successful data operation and sets the ReturnValue
property to the returned value. The fourth is also used for a successful data operation, but
when there is no predefined success message. It calls the third constructor, passing the
returned value and an empty string for the success message. Let’s now see the other class
that extends the DataOperationResult class:
using System;
namespace CompanyName.ApplicationName.DataModels
{
public class SetDataOperationResult : DataOperationResult<bool>
{
public SetDataOperationResult(Exception exception, string
errorText) :
base(exception, errorText) { }
public SetDataOperationResult(string successText) :
base(successText) { }
}
}
The SetDataOperationResult class is used for set operations and so has no return value.
Like the GetDataOperationResult class, its two constructors call the relevant base class
constructors. The first is used when an exception has been thrown and the second is used
for a successful data operation and accepts an input parameter for the operation’s success
message.
We’ll need to add a new method into our FeedbackManager class to enable us to add the
feedback messages from our GetDataOperationResult and SetDataOperationResult
classes directly. We’ll also include a parameter that allows us to override whether each
message will be displayed for its set duration, or until the user closes it manually. Let’s take
a look at that now:
public void Add<T>(DataOperationResult<T> result, bool isPermanent)
{
Add(new Feedback(result.Description, result.IsSuccess,
isPermanent));
}

Note that we use the DataOperationResult base class as the input parameter here, so that
either of our derived classes can be used with it. This method simply initializes a Feedback
object from the Description and IsSuccess properties of the DataOperationResult class
and passes it to the Add method that actually adds it to the Feedback collection.
If we’re going to be making asynchronous calls to the UI feedback control, then we’ll also
need to ensure that they are made on the UI thread, so as to avoid the common calling
thread cannot access this object because a different thread owns it exception.
To enable this, we need to add a reference to the UiThreadManager class that we discussed
earlier into our FeedbackManager class, although here, we add a reference to the
IUiThreadManager interface instead, to enable us to use a different implementation while
testing:
using System;
using CompanyName.ApplicationName.Managers.Interfaces;
private IUiThreadManager uiThreadManager = null;
public IUiThreadManager UiThreadManager
{
get { return uiThreadManager; }
set { uiThreadManager = value; }
}
public void Add(Feedback feedback)
{
UiThreadManager.RunOnUiThread((Action)delegate
{
Feedback.Add(feedback);
});
}
Using the IUiThreadManager interface, we simply need to wrap our single call to add
feedback to the FeedbackManager.Feedback collection property with the RunOnUiThread
method to run it on the UI thread. However, our uiThreadManager field needs to be
initialized before any feedback is displayed and we can do that from the first use of the
BaseViewModel class:
public BaseViewModel()
{
if (FeedbackManager.UiThreadManager == null)
FeedbackManager.UiThreadManager = UiThreadManager;
}
public IUiThreadManager UiThreadManager
{
get { return DependencyManager.Instance.Resolve<IUiThreadManager>

(); }
}
The first time that any View Model is instantiated, this base class constructor will be called
and the instance of the IUiThreadManager interface in the FeedbackManager class will be
initialized. Of course, in order to correctly resolve our instance of the IUiThreadManager
interface at runtime, we’ll first need to register it in the App.xaml.cs file, along with the other
registrations.
DependencyManager.Instance.Register<IUiThreadManager,
UiThreadManager>();
Let’s take a look at this interface and the classes that implement it now:
using System;
using System.Threading.Tasks;
using System.Windows.Threading;
namespace CompanyName.ApplicationName.Managers.Interfaces
{
public interface IUiThreadManager
{
object RunOnUiThread(Delegate method);
Task RunAsynchronously(Action method);
Task<TResult> RunAsynchronously<TResult>(Func<TResult> method);
}
}
The IUiThreadManager interface is a very simple affair and declares just three methods.
The RunOnUiThread method is used to run code on the UI thread, the first
RunAsynchronously method is used to run code asynchronously and the second
RunAsynchronously method is used to run methods that return something asynchronously.
Let’s now see the classes that implement it:
using System;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
using CompanyName.ApplicationName.Managers.Interfaces;
namespace CompanyName.ApplicationName.Managers
{
public class UiThreadManager : IUiThreadManager
{
public object RunOnUiThread(Delegate method)
{
return Application.Current.Dispatcher.Invoke(
DispatcherPriority.Normal, method);
}
public Task RunAsynchronously(Action method)
{
return Task.Run(method);
}

public Task<TResult> RunAsynchronously<TResult>(Func<TResult>
method)
{
return Task.Run(method);
}
}
}
In the UiThreadManager class, the RunOnUiThread method calls the Invoke method on the
Application.Current.Dispatcher object, to ensure that the method that is passed to it is
queued to run on the UI thread.
Basically, a dispatcher is responsible for maintaining the queue of work items for a
particular thread and each thread will have its own dispatcher. The Application.Current
property returns the Application object for the current AppDomain object and its
Dispatcher property returns the dispatcher of the thread that was running when the
application started - the UI thread.
As was seen earlier, the RunAsynchronously methods simply pass the methods specified by
the method input parameters to the Task.Run method. We also saw an example of mocking
the RunAsynchronously method in Chapter 1, A Smarter Way Of Working With WPF, but
now let’s see the whole MockUiThreadManager class, that we could use while testing our
application:
using System;
using System.Threading.Tasks;
using System.Windows.Threading;
using CompanyName.ApplicationName.Managers.Interfaces;
namespace Test.CompanyName.ApplicationName.Mocks.Managers
{
public class MockUiThreadManager : IUiThreadManager
{
public object RunOnUiThread(Delegate method)
{
return method.DynamicInvoke();
}
public Task RunAsynchronously(Action method)
{
Task task = new Task(method);
task.RunSynchronously();
return task;
}
public Task<TResult> RunAsynchronously<TResult>(Func<TResult>
method)
{
Task<TResult> task = new Task<TResult>(method);
task.RunSynchronously();
return task;
}
}
}

In the RunOnUiThread method, we simply call the DynamicInvoke method of the Delegate
class to run the method specified by the method input parameter. As we saw earlier, the
RunAsynchronously methods use the RunSynchronously method of the Task class to run the
methods specified by the method input parameters synchronously, to avoid timing problems
during testing.
In them, we first create a new Task object with the method specified by the method input
parameter, then call the RunSynchronously method on it and finally return the task. When
called using the await keyword, this will actually return the result of the method instead.
Let’s now see perhaps, the most important part of this functionality, where the
IUiThreadManager interface is used, the DataOperationManager class.
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Windows.Threading;
using CompanyName.ApplicationName.DataModels;
using CompanyName.ApplicationName.Managers.Interfaces;
namespace CompanyName.ApplicationName.Managers
{
public class DataOperationManager
{
private const int maximumRetryCount = 2;
private IUiThreadManager uiThreadManager;
public DataOperationManager(IUiThreadManager uiThreadManager)
{
UiThreadManager = uiThreadManager;
}
private IUiThreadManager UiThreadManager
{
get { return uiThreadManager.Instance; }
set { uiThreadManager = value; }
}
private FeedbackManager FeedbackManager
{
get { return FeedbackManager.Instance; }
}
public GetDataOperationResult<TResult> TryGet<TResult>(
Func<TResult> method, string successText, string errorText,
bool isMessageSupressed)
{
Debug.Assert(method != null, “The method input parameter of
the
DataOperationManager.TryGet<TResult>() method must not be
null.“);
for (int index = 0; index < maximumRetryCount; index++)
{
try
{
TResult result = method();
return WithFeedback(

new GetDataOperationResult<TResult>(result,
successText),
isMessageSupressed);
}
catch (Exception exception)
{
if (index == maximumRetryCount - 1)
{
return WithFeedback(
new GetDataOperationResult<TResult>(exception,
errorText),
isMessageSupressed);
}
Task.Delay(TimeSpan.FromMilliseconds(300));
}
}
return WithFeedback(
new GetDataOperationResult<TResult>(default(TResult),
successText),
isMessageSupressed);
}
private GetDataOperationResult<TResult>WithFeedback<TResult>(
GetDataOperationResult<TResult> dataOperationResult, bool
isMessageSupressed)
{
if (isMessageSupressed && dataOperationResult.IsSuccess)
return dataOperationResult;
FeedbackManager.Add(dataOperationResult, false);
return dataOperationResult;
}
public Task<GetDataOperationResult<TResult>>
TryGetAsync<TResult>(
Func<TResult> method, string successText, string errorText,
bool isMessageSupressed)
{
return UiThreadManager.RunAsynchronously(() =>
TryGet(method, successText, errorText,
isMessageSupressed));
}
public SetDataOperationResult TrySet(Action method,
string successText, string errorText, bool
isMessagePermanent,
bool isMessageSupressed)
{
Debug.Assert(method != null, “The method input parameter of
the
DataOperationManager.TrySet<TResult>() method must not be
null.“);
for (int index = 0; index < maximumRetryCount; index++)
{
try
{
method();
return WithFeedback(new
SetDataOperationResult(successText),

isMessagePermanent, isMessageSupressed);
}
catch (Exception exception)
{
if (index == maximumRetryCount - 1)
{
return WithFeedback(new
SetDataOperationResult(exception,
errorText), isMessagePermanent, isMessageSupressed);
}
Task.Delay(TimeSpan.FromMilliseconds(300));
}
}
return WithFeedback(new SetDataOperationResult(successText),
isMessagePermanent, isMessageSupressed);
}
private SetDataOperationResult WithFeedback(
SetDataOperationResult dataOperationResult,
bool isMessagePermanent, bool isMessageSupressed)
{
if (isMessageSupressed && dataOperationResult.IsSuccess)
return dataOperationResult;
FeedbackManager.Add(dataOperationResult, isMessagePermanent);
return dataOperationResult;
}
public Task<SetDataOperationResult> TrySetAsync(Action method)
{
return TrySetAsync(method, string.Empty, string.Empty);
}
public Task<SetDataOperationResult> TrySetAsync(Action method,
string successText, string errorText)
{
return TrySetAsync(method, successText, errorText, false,
false);
}
public Task<SetDataOperationResult> TrySetAsync(Action method,
string successText, string errorText, bool
isMessagePermanent,
bool isMessageSupressed)
{
return UiThreadManager.RunAsynchronously(() => TrySet(method,
successText, errorText, isMessagePermanent,
isMessageSupressed));
}
}
}
The DataOperationManager class starts with a couple of private fields, that represent the
maximum number of attempts to retry each data operation in case there is a problem and
the instance of the IUiThreadManager interface to use to run our functions asynchronously
when running the application.

The constructor enables us to inject the IUiThreadManager dependency that will be used
into the class and sets it to the private UiThreadManager property, which can only be
accessed from within the class. Likewise, the FeedbackManager property is also private and
enables us to pass feedback messages to the manager class to display them in the UI.
Next, we see the generic TryGet<TResult> method that returns an object of type
GetDataOperationResult<TResult>. More specifically, it returns a generic object of type
TResult, that is wrapped in one of our GetDataOperationResult objects. It first asserts that
the method input parameter is not null, as this class is based around this required
parameter.
In this method, we create a loop, with the number of its iterations determined by the value
of the maximumRetryCount field and inside the loop, we try to run the function specified by
the method input parameter. If the data operation is successful, we initialize a
GetDataOperationResult object, passing the return value and success feedback message
and return it via the WithFeedback method.
If an error occurs and the maximum number of attempts have not yet been reached, then
we use the asynchronous Task. Delay method to wait before attempting to run the method
again. If the maximum number of errors have been reached, then the exception and error
feedback message are wrapped in a GetDataOperationResult object and returned via the
WithFeedback method.
One improvement that we could implement here would be to increase this delay time each
time we retry the data operation. We could implement a function that returns an
exponentially increasing number, based on the maximumRetryCount field, representing the
millisecond value that will be passed to the Task. Delay method. This would be more likely
to better handle short network drop outs.
The WithFeedback method enables developers to suppress successful feedback messages,
as they might not always need the users to receive feedback. For example, we may not
need to inform them that their data objects were fetched from the database successfully, if
they have or will soon be displayed on the screen.
Therefore, if the data operation was successful and the isMessageSupressed input
parameter is true, the data operation result is returned directly, without feedback.
Otherwise, the dataOperationResult input parameter object is passed to the
FeedbackManager class to display the associated message, using the new methods that we
added earlier.
Next, we see the asynchronous TryGetAsync method, that simply calls the TryGet method
via the RunAsynchronously method of the UiThreadManager class. After that, we have the
TrySet method that is responsible for running all set data operations and returns an object
of type SetDataOperationResult.
This method is very similar to the TryGet method, except that it works for set data
operations. Similarly, it first asserts that the method input parameter is not null and then runs
the remainder of the code within a for loop. This again enables our retry capability and is
limited by the value of the maximumRetryCount field.
In the method, we try to run the function specified by the method input parameter and if the
data operation is successful, we initialize a SetDataOperationResult object, passing just

the success feedback message and return it via the WithFeedback method.
If an error occurs and the number of attempts specified by the maximumRetryCount field
have not yet been reached, then we use the Task. Delay method to wait before attempting
to run the method again. If the maximum number of errors have been reached, then the
exception and error feedback message are wrapped in a SetDataOperationResult object
and returned via the WithFeedback method.
The WithFeedback method used with the SetDataOperationResult objects works exactly
the same as the earlier one that works with the generic GetDataOperationResult objects.
Finally, we have some overloaded TrySetAsync methods, that end up calling the TrySet
method asynchronously via the RunAsynchronously method of the UiThreadManager class.
One point to note here is that currently, this class is located in the Managers project. If we
were at all likely to need to swap out our data access technology, then we might prefer to
move this class to the data access project for ease of removal. As it stands, we don’t have
that requirement and so, it is fine where it is.
We can make use of this DataOperationManager class in the DataController class that we
saw earlier, with just a few changes. We can also replace its previous
SetAuditCreateFields and SetAuditUpdateFields methods with some new methods that
also update our data models that implement the ISynchronizableDataModel interface. Let’s
take a look at the new code in there:
using System;
using System.Threading.Tasks;
using CompanyName.ApplicationName.DataModels;
using CompanyName.ApplicationName.DataModels.Collections;
using CompanyName.ApplicationName.DataModels.Enums;
using CompanyName.ApplicationName.DataModels.Interfaces;
using CompanyName.ApplicationName.Managers;
using CompanyName.ApplicationName.Models.Interfaces;
namespace CompanyName.ApplicationName.Models.DataControllers
{
public class DataController
{
private DataOperationManager dataOperationManager;
public DataController(IDataProvider dataProvider,
DataOperationManager dataOperationManager, User currentUser)
{
DataOperationManager = dataOperationManager;
CurrentUser = currentUser.Clone();
}
protected DataOperationManager DataOperationManager
{
get { return dataOperationManager; }
private set { dataOperationManager = value; }
}

public Task<SetDataOperationResult> AddProductAsync(Product
product)
{
return DataOperationManager.TrySetAsync(() =>
DataProvider.AddProduct(InitialiseDataModel(product)),
$“{product.Name} was added to the data source
successfully”, $“A
problem occurred and {product.Name} was not added to the
data
source.“);
}
public Task<SetDataOperationResult> DeleteProductAsync(
Product product)
{
return DataOperationManager.TrySetAsync(() =>
DataProvider.DeleteProduct(DeleteDataModel(product)),
$“{product.Name} has been deleted from the data source
successfully.“, $“A problem occurred and {product.Name} was
not
deleted from the data source.“, true, false);
}
public Task<GetDataOperationResult<Products>>
GetProductsAsync()
{
return DataOperationManager.TryGetAsync(() =>
DataProvider.GetProducts(), string.Empty, “A problem
occurred when
trying to retrieve the products.“, true);
}
public SetDataOperationResult UpdateProduct(Product product)
{
return DataOperationManager.TrySet(() =>
DataProvider.UpdateProduct(UpdateDataModel(product)),
$“{product.Name} was saved in the data source
successfully.“, $“A
problem occurred and {product.Name} was not updated in the
data
source.“, false, false);
}
private T InitialiseDataModel<T>(T dataModel)
where T : class, IAuditable, new()
{
dataModel.Auditable = new Auditable(dataModel, CurrentUser);
if (dataModel is ISynchronizableDataModel<T>)
{
ISynchronizableDataModel<T> synchronisableDataModel =
(ISynchronizableDataModel<T>)dataModel;
synchronisableDataModel.ObjectState = ObjectState.Active;
}
return dataModel;
}
private T DeleteDataModel<T>(T dataModel)

where T : class, IAuditable, new()
{
dataModel.Auditable.UpdatedOn = DateTime.Now;
dataModel.Auditable.UpdatedBy = CurrentUser;
if (dataModel is ISynchronizableDataModel<T>)
{
ISynchronizableDataModel<T> synchronisableDataModel =
(ISynchronizableDataModel<T>)dataModel;
synchronisableDataModel.ObjectState = ObjectState.Deleted;
}
return dataModel;
}
private T UpdateDataModel<T>(T dataModel)
where T : class, IAuditable, new()
{
dataModel.Auditable.UpdatedOn = DateTime.Now;
dataModel.Auditable.UpdatedBy = CurrentUser;
return dataModel;
}
}
}
We start this class with the dataOperationManager field of type DataOperationManager. We
don’t need to use an interface here, as this class is safe to be used during testing.
However, it contains a member of type IUiThreadManager, and we need to be able to use
different implementations of this, dependent upon whether we’re running or testing the
application.
Therefore, we still need to inject the instance of the dataOperationManager field to use
through the constructor, so that it’s instance of the IUiThreadManager interface can be
resolved in the calling code. After the constructor, we see the private
DataOperationManager property, that can only be set from within the class.
The first of the new methods is the AddProductAsync method and as a set operation, it
returns a Task of type SetDataOperationResult. Internally and like all async set operations
here, it calls the TrySetAsync method of the DataOperationManager class. It passes the
method to run asynchronously and the success and unspecified error text to be displayed
as user feedback.
Note that we pass the product input parameter to the InitialiseDataModel method,
before passing it to the AddProduct method of the IDataProvider instance, to initialize the
base class Auditable property before it is stored in the database.
If the current instance also extends the ISynchronizableDataModel interface, then its
ObjectState property will be set to the Active member of the ObjectState enumeration.
This idea could easily be extended; if we had an IIdentifiable interface with a single
identification property, we could initialize that here also.
The DeleteProductAsync method also returns a Task of type SetDataOperationResult and
calls the TrySetAsync method of the DataOperationManager class, but it uses a different
overload, which enables the feedback message to be displayed permanently, or until the
user manually closes it. In this example, it is used to ensure that the user is aware that the
product was deleted.

In this method, we pass the product input parameter to the DeleteDataModel method,
before passing it to the DeleteProduct method of the IDataProvider instance. This sets the
UpdatedOn property of the Auditable class to the current date and time and the UpdatedBy
property to the currently logged in user. If the current instance extends the
ISynchronizableDataModel interface, then its ObjectState property will also be set to a
state of Deleted.
The next new method is the GetProductsAsync method, which is a get operation and returns
a Task of type GetDataOperationResult<Products>. Internally and like all async get
operations, it calls the TryGetAsync method of the DataOperationManager class. It passes
the method to run asynchronously and the unspecified error text to be displayed as user
feedback.
Of particular note here is the bool parameter that it passes, which suppresses any
successful feedback message from being displayed. If there is an error, either the provided
error message or a more well defined custom error message will be displayed still, but as
no successful message will be displayed, we simply pass an empty string through for that
parameter.
The final new data operation method is the UpdateProduct method, which is not
asynchronous, and returns a SetDataOperationResult directly. Instead of the TrySetAsync
method, it calls the TrySet method of the DataOperationManager class and passes the
method to run, the success and error messages and two bool parameters to signify that it
should display the feedback normally.
Internally, it passes the product input parameter to the UpdateDataModel method, before
passing it to the UpdateProduct method of the IDataProvider instance. This sets the
UpdatedOn property of the Auditable class to the current date and time and the UpdatedBy
property to the currently logged in user.
This gives an example of how we might build up our data operation methods, predominantly
using asynchronous access methods, but not restricted to having to do so. Of course, there
are many ways of accessing data in an application and you should experiment with the way
that suits you best. This way would suit larger scale applications best, as there is a fair
amount of overhead in creating this system.
However, there’s still one piece of the puzzle missing. Now that we’ve changed the
constructor of the DataController class, we’ll also need to update our BaseViewModel
class, which exposes it, again.
protected DataController Model
{
get { return new DataController(
DependencyManager.Instance.Resolve<IDataProvider>(),
new DataOperationManager(UiThreadManager),
StateManager.CurrentUser); }
}
public IUiThreadManager UiThreadManager
{
get { return DependencyManager.Instance.Resolve<IUiThreadManager>

(); }
}
Now, the IDataProvider implementation is resolved by the DependencyManager instance,
along with the IUiThreadManager implementation that gets injected into the
DataOperationManager object. In addition to this, we pass the value of the
StateManager.CurrentUser property to the DataController class constructor to instantiate
it each time it is requested.
Now, we have a system in place that can run our data operations either synchronously or
asynchronously and retry our data operations a specified number of times if they fail, before
finally reporting custom feedback messages to the user.
We can customize how long these messages remain visible, before automatically
disappearing, or whether they will automatically disappear or not, or even whether they are
displayed in the first place or not. Even with these options, the system remains lightweight
and can be easily added to.

Going the extra mile
Most privately developed applications are primarily functional, with little time and effort
spent on design concerns and even less on usability. How many times have we seen
applications that throw out a stack trace to the end user when an error occurs, or validation
messages that highlight errors with the camel case code names for fields, rather than the
labels used in the UI?
In a good application, the end user should never be presented with any code-based
terminology. If we were writing an English based application, we wouldn’t output error
messages in Spanish, so why output them in C#? This can confuse the user and even alarm
them in some cases.
How many times have you used an application that has an awkward process flow to
perform each task, that involves far more mouse clicks than is necessary? This section is
dedicated to avoiding these kinds of situations and suggests a number of ways of improving
the usability of our applications.
Producing in-application help
In an ideal world, we would all create applications that were so intuitive that we wouldn’t
need to provide in-application help. However, with the complexity of some of today’s
applications, this is not always possible. It is therefore often helpful to provide the end users
of our applications with some form of help that they can refer to when necessary.
There are a number of ways of doing this, with the first simply being to provide a link to a
separate help file from the application. If we have a PDF, or other type of file that contains
help for the users, we can add it to our solution in Visual Studio as a resource.
To do this, we can add a Resources folder into our solution and then select the Add New
Item option in the new folder’s context menu. After navigating to the help file in the Add
New Item dialog and successfully adding it, we can view its properties, by selecting it in the
Solution Explorer and pressing F4, or right clicking it and selecting Properties from the
context menu.
Once the properties are displayed, we can verify that the file has been added with a Build
Action of Content and a Copy to Output Directory value of Copy always or Copy if
newer, which ensures that our help file and its Resources folder will be copied to the folder
that contains the application executable file and that the newest version will always be used.
We can then add a menu item or button to our application, that the users can select to open
the document directly. In our View Model command that is data bound to this control, we
can call the Start method of the Process class, passing the path of the help file, to open
the file in the default application on the user’s computer.
System.Diagnostics.Process.Start(filePath);
We can get the folder path of the application executable file using the following code:
string filePath = System.AppDomain.CurrentDomain.BaseDirectory;
Therefore, if our Resources folder is in the startup project, we could attain its folder path
like this:

string filePath = Path.Combine(
new DirectoryInfo(System.AppDomain.CurrentDomain.BaseDirectory).
Parent.Parent.FullName, “Resources”);
This utilizes the DirectoryInfo class to access the parent folder of the parent folder of the
executable file, or the root directory of the project, and the Combine method of the Path
class to create a file path that combines the new Resources folder with that path.
If we don’t have a complete documentation file for our application, a quick and simple
alternative would be to add an information icon to each View. This image control could
display pertinent information to the users in a tooltip when they place their mouse pointer
over it.
Using the information icon from the Visual Studio Image Library that was discussed in
Chapter 7, Creating Visually Appealing User Interfaces, we can create these help points
like this:
<Image Source=“pack://application:,,,/CompanyName.ApplicationName;
component/Images/Information_16.png” Stretch=“None” ToolTip=“Here
is
some relevant information” />
Either way, the idea is to provide the users of the application with any help that they may
need right from the application itself. This not only improves the usability of our applications,
but also reduces user errors and increases data quality.
Enabling user preferences
The users of our applications are likely to be very different to each other, or at least have
their individual preferences. One user may prefer to work in one way, while another may
have different preferences. Providing the ability for them to customize the application to suit
the way that they work will increase the usability of the application for them.
This may relate to the View that they prefer to see when the application starts, or to which
particular options in each View that they prefer to use, or even to the size and position of
the application when it was last used. There are any number of preferences that we can
offer each user.
Luckily, we can offer this customization functionality with minimal work, as the .NET
Framework provides us with settings files for just this purpose. These settings can either
have application or user scope and can be mixed and matched in each settings file.
Application settings are the same for each user and are suited to storing configuration
settings, such as e-mail server details or credentials. User settings can be different for each
user and are suited to the kind of personal customizations just discussed.
Typically, the startup project will already have a settings file named Settings.settings. It
can be found by opening the Properties folder in the Solution Explorer in Visual Studio
and opened by double-clicking on it. Alternatively, you can right-click on the project in the

Solution Explorer, select the Properties option and then select the Settings tab.
Settings files can also be added to other projects, although they are not typically available
by default. In order to add a settings file to another project, we first need to open the
project properties by right clicking on the project in the Solution Explorer and selecting the
Properties option.
In the project properties window, select the Settings tab and click the link that says This
project does not contain a default settings file. Click here to create one. A settings file
will be created within the project Properties folder in the Solution Explorer. We are then
free to start adding our user preferences.
To add our custom settings, click a blank row in the settings file and enter the name, data
type, scope and default value of the setting. The name will be used in code and so, cannot
contain spaces. We can select our own custom data types, although whichever type we
select must be serializable. The default value is the initial value that the setting will have
before the user changes it.
Settings will usually be loaded upon application startup and saved just before application
shutdown. As such, it is customary to attach event handlers to the Loaded and Closed
events in the MainWindow.xaml.cs file, although we can also do it in the App.xaml.cs file if
we have configured the application to use it. We can see a typical example here:
using System;
using System.Windows;
using CompanyName.ApplicationName.ViewModels;
namespace CompanyName.ApplicationName
{
public partial class MainWindow : Window
{
public MainWindow()

{
InitializeComponent();
Loaded += MainWindow_Loaded;
Closed += MainWindow_Closed;
}
private void MainWindow_Loaded(object sender, RoutedEventArgs
e)
{
MainWindowViewModel viewModel = new MainWindowViewModel();
viewModel.LoadSettings();
DataContext = viewModel;
}
private void MainWindow_Closed(object sender, EventArgs e)
{
MainWindowViewModel viewModel =
(MainWindowViewModel)DataContext;
viewModel.SaveSettings();
}
}
}
We attach the two event handlers in the constructor, right after the components are
initialized. In the MainWindow_Loaded method, we instantiate an instance of the
MainWindowViewModel class, call its LoadSettings method and set it as the window’s
DataContext property value.
In the MainWindow_Closed method, we access the instance of the MainWindowViewModel
class from the DataContext property, but this time, call its SaveSettings method. Now, let’s
see these methods in the MainWindowViewModel.cs file:
using CompanyName.ApplicationName.ViewModels.Properties;
public void LoadSettings()
{
Settings.Default.Reload();
StateManager.AreAuditFieldsVisible =
Settings.Default.AreAuditFieldsVisible;
StateManager.AreSearchTermsSaved =
Settings.Default.AreSearchTermsSaved;
}
public void SaveSettings()
{
Settings.Default.AreAuditFieldsVisible =
StateManager.AreAuditFieldsVisible;
Settings.Default.AreSearchTermsSaved =
StateManager.AreSearchTermsSaved;
Settings.Default.Save();
}
The first thing that we need to do in the LoadSettings method is to call the Reload method
on the default instance of the settings file. This loads the settings from the settings file into
the Default object. From there, we set each settings property to its corresponding property

that we created in our StateManager class, for use in the application.
Note that the values of each user’s personal settings are not stored in the
Settings.settings file. Instead, they are stored in their AppData folder, which is hidden by
default. The exact file path can be found using the ConfigurationManager class, but to find
it, we’ll need to add a reference to the System.Configuration DLL and use the following
code:
using System.Configuration;
string filePath = ConfigurationManager.OpenExeConfiguration(
ConfigurationUserLevel.PerUserRoamingAndLocal).FilePath;
In my case, that resolves to the following file path:
C:\Users\Sheridan\AppData\Local\CompanyName</span>
CompanyName.ApplicationNa_Url_0nu0qp14li5newll2223u0ytheisf2gh</span>
1.0.0.0\user.config
Note that the folder in the CompanyName folder is named using a particular identification
number that relates to the current settings and application version. Over time and after
making changes, new folders will appear here with new identification numbers, but this is all
totally transparent to the users, as their previous settings will be safely transferred.
Extending common courtesies
One area of application development where we can easily make great improvements is
usability. Many applications these days are created with little or no concern for the end
users that will be using the application each day.
We’ve probably all seen applications that spew out exception stack traces when errors
occur and while we, as developers, may find that useful, it can be confusing, or even
alarming for the end users. Instead of worrying the end users unnecessarily, we can output
stack traces and any other pertinent information about each error to an Errors table in our
database.
Extending this idea further, it is good working practice to totally avoid using any
development terms or phrases anywhere in the application that the users can see. That
includes all UI labels, along with any additional external help files and/or documentation.
Using terms of this kind will make the application more difficult to use, especially for new
users. All but the best known abbreviations should also be avoided.
We can further humanize our application by paying attention to the small details. How often
have you come across an application that displays a label that says something like “1
passengers”, or “2 item”. While this is a very simple problem to fix, it is commonly found in
many applications. Let’s create a new Extension method to encapsulate this useful
functionality in an IntegerExtensions class:
public static string Pluralize(this int input, string wordToAdjust)
{
return $“{wordToAdjust}{(input == 1 ? string.Empty : “s”)}“;
}

In this example, we simply use string interpolation to append an s to the end of the
wordToAdjust input parameter when the value of the this input parameter is not 1. While
this will work for most words that we are likely to use, it is worth noting that there are some
groups of words that this will not work with.
For example, some words, such as “Activity”, end with a “y” in their singular form and will
end with “ies” when pluralized. However, this problem can be easily addressed by either
adding a new overload of our Pluralize method, or an additional input parameter that
enables the users of our code to specify the transformation that they require.
With this method, we now have a really simple way to always ensure that our spelling is
correct when dealing with quantities. Let’s see how we might use this method to pluralize
the word Ticket, but only when the amount of tickets in the Tickets collection is not 1.
public string TicketCountText => Tickets.Count.Pluralize(“Ticket”);
An extension to this method could combine this functionality with the actual number to output
6 Tickets for example. Let’s take a look at this new method.
public static string Combine(this int input, string wordToAdjust)
{
return $“{input} {wordToAdjust}{(input == 1 ? string.Empty :
“s”)}“;
}
The Combine method is very similar to the Pluralize method, except that also includes the
value of the input input parameter in the text output. We could also extend this method in
the same way that we could extend the Pluralize method, to handle the pluralization of
words other than those that just require an s to be appended. We can also use it in the
same way:
public string TicketCountText => Tickets.Count.Combine(“Ticket”);
Another way that we could humanize our textual output would be to provide a selection
summary field that displays a comma-separated list of the selected items in a collection
control. Clearly, this would be unrequired for controls that only allow single selections to be
made however, it could be a useful confirmation for those using multiple selection collection
controls. Let’s see how we could declare a ToCommaSeparatedString method now:
using System.Text;
public static string ToCommaSeparatedString<T>(
this IEnumerable<T> collection)
{
StringBuilder stringBuilder = new StringBuilder();
int index = 0;
foreach (T item in collection)
{
if (index > 0)
{
if (index < collection.Count() - 1) stringBuilder.Append(“,
”);
else if (index == collection.Count() - 1)

stringBuilder.Append(” and “);
}
stringBuilder.Append(item.ToString());
index++;
}
return stringBuilder.ToString();
}
Here, we have a method that we can call on any collection that is either of the type of, or
extends the IEnumerable<T> interface and receive a string back that contains a comma-
separated list of each contained element. We can either call it with a string collection, or
implement the object.ToString method in our classes, as that will be called on each
element.
This method uses the StringBuilder class to build the comma-separated list. As the
StringBuilder class has a slight overhead when being initialized and when exporting the
constructed string, tests have shown that it only really offers an improvement in time over
basic string concatenation when appending ten or more strings.
You may therefore prefer to refactor this method to remove the StringBuilder object,
although you may also find that the difference in milliseconds is negligible. Returning to the
method, after declaring the StringBuilder object, we initialize the index variable, which is
used to specify which separator to join each string with.
When the index variable equals zero and no strings have yet been added to the
StringBuilder object, no separator will be appended. After that, we check whether the
current string is the last in the collection and if it is, we prepend “ and” to it, otherwise we
prepend a comma and space to it.
After each iteration, we increment the index variable and when finished, we return the
output from the StringBuilder object. It could be used to display a comma-separated list
of the products that a user has selected like this:
SelectedProducts.Select(p => p.Name).ToCommaSeparatedString();
As you can see, there are many ways that we can humanize our output for the end users, in
order to make them feel more at ease when using our applications. Let’s now move on to
see other ways that we can provide that great user experience for our users.
Un-burdening the end user
There are many things that we can do to make the life of the end users easier. One simple
example would be to set the focus in a form to the first field, so that users can start typing
as soon as they load a view, without first needing to focus it manually.
We saw one way to do this using an Attached Property in Chapter 4, Becoming Proficient
With Data Binding, but we can also achieve this easily, by first adding a new bool property
into our BaseViewModel class.
private bool isFocused = false;
public bool IsFocused
{
get { return isFocused; }

set { if (isFocused != value) { isFocused = value;
NotifyPropertyChanged(); } }
}
Next, we can add a style resource into the application resources in the App.xaml file:
<Style TargetType=“{x:Type TextBox}“>
<!– Define default TextBox style here –>
</Style>
<Style x:Key=“FocusableTextBoxStyle” TargetType=“{x:Type TextBox}”
BasedOn=“{StaticResource {x:Type TextBox}}“>
<Style.Triggers>
<DataTrigger Binding=“{Binding IsFocused}” Value=“True”>
<Setter Property=“FocusManager.FocusedElement”
Value=“{Binding RelativeSource={RelativeSource Self}}” />
</DataTrigger>
</Style.Triggers>
</Style>
This assumes that we already have a default style that we want to use for our textboxes
and that our new style will be based on that, but add this additional focusable functionality.
It simply consists of a single data trigger that uses the FocusedElement property of the
FocusManager class to focus the textbox element that has this style applied to it when the
IsFocused property is set to true.
Therefore, all we need to do to focus a particular textbox in a View is to apply this style to it
and set the IsFocused property from the BaseViewModel class to true in the appropriate
place in the related View Model.
IsFocused = true;
Note that the textbox will become focused as the property becomes true and so, if the
property is already true, we may need to first set it to false before again setting it to true
to get this to work. For example, if the property was true before the View was loaded, then
the textbox would not become focused.
Another simple example of making our application users’ lives easier would be to pre-
populate any form fields that we may be able to. For example, if our application has a login
screen that uses the users’ Windows username, we could fill in the user name field in the
form after accessing it from the WindowsIdentity class like this:
UserName = WindowsIdentity.GetCurrent().Name;
Another example of this might be to pre-populate form fields with the most commonly used
values. We could perhaps fill in a date field to today’s date, or an Amount Paid field to the
total amount, if that is what the users typically do.
We do however need to be careful when doing this, because if we get the default value(s)
wrong, it could backfire and actually take the users longer to delete the default value and
replace it with the value that they want than to just input the value directly. Remember, the
idea is to save the users time and make them more productive.
Quite often, we can save the users of our applications a great amount of time. If we have
the chance to ask them exactly what they do and how they would use the application on a
day to day basis, then we can usually program a lot of their operations into functions in the

application.
For example, if any users have to repeatedly edit a number of files with the same data,
perhaps to add, remove, or update a particular field, then we could build that functionality
straight into the application.
Instead of making them edit a single record at a time, we could provide a View where they
set the field or fields to change and the new value(s), along with the ability to select multiple
records, and therefore save them a great deal of time and effort.
All menial, or repetitive tasks can be programmed into functions and so, writing a good
application is not just restricted to making pretty and asynchronous UIs, but also to making
it highly usable. Furthermore, the more useful the application is, the more productive the
users will become, and the more lavish the praise that will be bestowed on us and our
development teams, if applicable.

Summary
In this chapter, we discussed further ways to improve our applications, making them as
useful to the end users as possible. We investigated how we could implement a custom
user feedback system to keep the users informed with the status of the operations that
they perform.
We also examined how to make our applications asynchronous, so that our UI won’t freeze
when the application is performing long running operations. We then looked at one way of
building this asynchronous behavior right into our application framework, so that we can run
any data access operation asynchronously, with minimal code.
We ended with a short section dedicated to improving the way that our applications are
perceived by the end users. In it, we detailed a number of ways of accomplishing this, from
providing in-application help and user preferences to paying attention to the smaller details
and implementing work-heavy functions to save the users from having to manually do the
same.
In the next chapter, we’ll be looking at a number of ways that we can improve the
performance of our applications, from utilizing the power of installed graphics cards, to
writing more efficient code. We’ll also look into how we can improve the efficiency of our
data bindings and resources and investigate other techniques, such as data virtualization.

Chapter 10. Improving Application
Performance
The performance of WPF applications in general is one of their biggest problems. The more
visual layers that our rendered data objects and UIs contain, the more time it takes to
render them, so we often need to maintain a balance between making our applications
visually appealing and making them perform better.
This situation can be improved by running our WPF applications on more powerful
computers. This explains why these applications are most prevalent in the financial industry.
However, not everyone can afford to update all of their users’ computers for this purpose.
Luckily, there are a number of ways that we can improve the performance of our WPF
applications and we’ll investigate them here. The art of improving application performance
really comes down to making a lot of small improvements that together, add up to a
noticeable difference.
In this chapter, we’ll explore how we can better utilize the graphics rendering power of our
computer’s graphics card and declare our resources more efficiently. We’ll investigate how
we can improve our application’s performance by opting to use lighter weight UI controls,
more efficient data binding modes and employing other techniques, such as virtualization.
Leveraging the power of hardware
rendering
As we’ve learnt, the visuals that WPF can output, while beautiful, can be very CPU intensive
and we often need to bear this in mind when designing our Views. However, rather than
compromising our designs, we can offload the intensive rendering processes to the host
computer’s Graphics Processing Unit (GPU) instead.
While WPF will default to utilize its software rendering pipeline, it is also able to take
advantage of a hardware rendering pipeline. This hardware pipeline leverages features of
Microsoft DirectX, as long as the host PC has DirectX version 7 or higher installed.
Furthermore, if the version of DirectX that is installed is version 9 or higher, increased
performance improvements will be seen.
The WPF Framework looks at the graphics hardware that is installed on the computer that
it is running on and puts it into one of three categories, depending on its features, such as
video RAM, shaders, and support for multi-textures. If it does not support version 7 of
DirectX or higher, then it is classed in Rendering Tier 0 and will not be used for hardware
rendering at all.
However, if it does support DirectX version 7 or higher, but less than version 9, then it is
classed in Rendering Tier 1 and will be used for partial hardware rendering. But as
practically all new graphics cards support versions of DirectX higher than 9, they would all
be classed in Rendering Tier 2 and would be used for full hardware rendering.
As the UI will freeze during the rendering time, care should be taken to minimize the number
of visual layers that are rendered. Therefore, for WPF applications that will run on

computers that have graphics hardware classed in Rendering Tier 0 and use software
rendering, we need to take extra care.
However, if our application is likely to be run on older computers, or computers with older
graphics hardware, we can detect this using the rendering tier and run more efficient code
in these instances. We can find out the rendering tier of the host computer’s graphics
hardware using the static Tier property of the RenderCapability class.
Unfortunately, instead of the type of this property being some kind of useful enumeration, it
is in fact an integer, where just the high-order word represents the value of the tier and can
be either 0, 1, or 2. We can attain it by shifting the bits in the integer to read the value from
just the last two bytes:
using System.Windows.Media;
int renderingTier = RenderCapability.Tier >> 16;
Once we know the rendering tier of the host computer’s graphics hardware, we can write
code accordingly. For example, let’s imagine that we had a processor-intensive View, with
lots of visuals making up each item in a collection. We could set the tier value into a
property and data bind it to the View, where we could select different data templates to use
dependent upon the processing power of the host computer. Let’s examine this example, by
first creating that missing enumeration:
namespace CompanyName.ApplicationName.DataModels.Enums
{
public enum RenderingTier
{
Zero = 0,
One = 1,
Two = 2
}
}
Next, we need to add a property of type RenderingTier into our StateManager class from
Chapter 3, Writing Custom Application Frameworks.
public RenderingTier RenderingTier { get; set; }
We don’t need to inform the INotifyPropertyChanged interface of changes to this property
because it will only be set once upon application startup. Let’s adjust our previous example:
public App()
{
StateManager.Instance.RenderingTier =
(RenderingTier)(RenderCapability.Tier >> 16);
}
After casting the bit shifted integer value into our RenderingTier enumeration and setting it
to the new RenderingTier property in the StateManager class, we can then start to use it in
our Views to determine the level of visualizations that we can employ:
<ListBox ItemsSource=“{Binding Products}”>
<ListBox.Style>
<Style TargetType=“{x:Type ListBox}“>

<Setter Property=“ItemTemplate”
Value=“{StaticResource SimpleDataTemplate}” />
<Style.Triggers>
<DataTrigger Binding=“{Binding
StateManager.Instance.RenderingTier}” Value=“One”>
<Setter Property=“ItemTemplate”
Value=“{StaticResource MoreComplexDataTemplate}” />
</DataTrigger>
<DataTrigger Binding=“{Binding
StateManager.Instance.RenderingTier}” Value=“Two”>
<Setter Property=“ItemTemplate”
Value=“{StaticResource MostComplexDataTemplate}” />
</DataTrigger>
</Style.Triggers>
</Style>
</ListBox.Style>
</ListBox>
In this example, we have a ListBox control that is displaying a collection of products. The
idea is that we can declare three different data templates to define what each product will
look like. We have a SimpleDataTemplate template that might just provide a text-based
output, a MoreComplexDataTemplate template, that could contain some basic visuals and a
MostComplexDataTemplate template, that could contain several layers of visuals.
In the style that is applied to the list box, we set the default SimpleDataTemp late template
as the value of its ItemTemplate property. Using the RenderingTier property of the
StateManager class, we then declare a couple of data triggers to switch the value of the
ItemTemplate property to one of the more complex templates, dependent upon the
rendering tier of the host computer.

Making more efficient resources
When we reference our resources, we can either use a StaticResource or a
DynamicResource. If you remember from Chapter 5, Using The Right Controls for The Job,
a StaticResource will look up the value of the resource just once, which is comparative to a
compile-time lookup. A DynamicResource will repeatedly look up the value of the resource
each time it is requested, whether it has changed or not, like a runtime lookup.
For this reason, we should only ever use a DynamicResource if we really need to and can
attain much better performance by using the StaticResource class instead. If we find that
we need to use a lot of DynamicResource references to access our resources, then we can
refactor our code to data bind to properties in our StateManager class instead of the
resources, to increase performance.
Another simple way to improve the performance of our resources is to reuse them. Instead
of declaring them inline in the place that they are used in the XAML, we should declare
them in a suitable resource section and reference them.
In this way, each resource is created just once and shared. To extend this idea further, we
could define all of our shared resources in the application resources in the App.xaml file and
share them between all of the application Views.
Imagine a situation where some brush resources were declared inline with the XAML within
a DataTemplate element. Now imagine that this template is set as the ItemTemplate of an
ItemsControl object and that the collection that is data bound to its ItemsSource property
contains a thousand elements.
The application will therefore create a thousand brush objects with identical properties for
each brush that is declared locally within the data template. Now compare this to the
situation where we declare each required brush just once in a resource section and
reference it from the template. It’s clear to see the benefit of this method and the huge
savings that can be made of the computer’s resources.
Furthermore, this idea also affects the Resources sections of our Views, if we will be
displaying more than one of them at once. If we declare a View to define how each object
in a collection should be rendered, then all of the resources that are declared in the View
will be initialized once for each element in the collection. In this case, it is better to declare
them at the application level.
Freezing objects
In WPF, certain resource objects, such as animations, geometries, brushes and pens, can
be made Freezable. This provides special features that can help to improve the
performance of our WPF applications. Freezable objects can either be frozen or unfrozen.
In the unfrozen state, they behave like any other object, but when frozen, they become
immutable and can no longer be modified.
The main benefit of freezing objects is that it can improve application performance, because
frozen objects no longer require resources to be consumed on monitoring and issuing
change notifications. Another benefit is that a frozen object is also safe to be shared across
threads, unlike unfrozen objects.

Many UI-related objects extend the Freezable class to provide this functionality and most
Freezable objects relate to the graphics sub-system, as rendering visuals is one of the
areas where performance improvements are most needed.
Classes such as the Brush, Geometry and Transform classes contain unmanaged resources
and the system must monitor them for changes. By freezing these objects and making them
immutable, the system is able to free up its monitoring resources and better utilize them
elsewhere. Furthermore, even the memory footprint of a frozen object is considerably less
than its unfrozen counterpart.
Therefore, in order to make the greatest performance improvements, we should get used
to freezing all of our resources in all Resource sections, as long as we have no plans to
modify them. As most resources typically remain unmodified, we are usually able to freeze
the vast majority of them and gain significant and noticeable improvements in performance
by doing so.
In Chapter 7, Creating Visually Appealing User Interfaces, we saw how we can freeze a
Freezable object in code by calling its Freeze method. Let’s now see how we can freeze
our resources in XAML. First, we need to add an XML namespace prefix to the
presentation options namespace to access its Freeze attribute:
xmlns:PresentationOptions=
compatibility/2006”
mc:Ignorable=“PresentationOptions”
Note that we also include another XML namespace prefix to be able to access the
Ignorable attribute and we set our PresentationOptions prefix as its value. This is
because the Freeze attribute is primarily only recognized by the WPF XAML processor and
in order to maintain compatibility with other XAML readers, we need to specify that the
attribute can be ignored.
We’ll see a full example in the Drawing Conclusions section coming up soon, but for now
and using a resource from an earlier example, let’s see how to freeze a Freezable object in
XAML:
<DropShadowEffect x:Key=“Shadow” BlurRadius=“10” Direction=“270”
ShadowDepth=“7” Opacity=“0.5” PresentationOptions:Freeze=“True”
/>
Some Freezable objects, such as the animation and geometry objects, can contain other
Freezable objects. When a Freezable object is frozen, its child objects are also frozen.
However, there are a few cases where a Freezable object cannot be frozen.
One case happens if it has any properties that might change value, due to either
animations, data binding, or DynamicResource references. The other case occurs when the
Freezable object has any child objects that cannot be frozen.
If we are freezing resource type objects in the code behind of a custom control, for
example, then we can call the CanFreeze property of the Freezable class to check whether
each Freezable object can be frozen before attempting to freeze them.
EllipseGeometry ellipseGeometry =

new EllipseGeometry(new Rect(0, 0, 500, 250));
if (ellipseGeometry.CanFreeze) ellipseGeometry.Freeze();
Path.Data = ellipseGeometry;
Once a Freezable object is frozen, it cannot be modified and attempting to do so will cause
an InvalidOperationException to be thrown. Note that a Freezable object cannot be
unfrozen, so to avoid this situation, we can check the value of the IsFrozen property before
attempting to modify the object. If it is frozen, we can make a copy of it using its Clone
method and modify that instead:
if (ellipseGeometry.IsFrozen)
{
EllipseGeometry ellipseGeometryClone = ellipseGeometry.Clone();
ellipseGeometryClone.RadiusX = 400;
Path.Data = ellipseGeometry;
}
else ellipseGeometry.RadiusX = 400;
If a Freezable object is cloned, any Freezable children that it may have will also be copied
to enable modification. When a frozen object is animated, the animation system will make
cloned copies of it in this way so that it can modify them, but as this adds an overhead to
performance, it is advisable not to freeze a Freezable object if it is expected to be
animated.

Using the right controls for performance
As was mentioned previously, there are usually several different ways of achieving the
same functionality, or UI display when using WPF. Some ways will provide better
performance than others. For example, we saw how some panels do more intensive layout
work and therefore consume more CPU cycles and/or RAM than others.
Therefore, this is one area that we can investigate in order to make performance
improvements. If we do not require the complex layout and resizing abilities of a Grid panel,
then we can gain a performance improvement by utilizing a more efficient StackPanel or
Canvas panel instead.
Another example could be that if we do not require the ability to select in a collection
control, then we should use an ItemsControl element instead of a ListBox. While swapping
one control will not make much of a performance improvement on its own, making this same
swap in the DataTemplate of an item that will be displayed thousands of time will make a
noticeable difference.
As we discovered in Chapter 5, Using The Right Controls for The Job, each time a UI
element is rendered, the layout system must complete two passes, a measure pass and an
arrange pass, collectively known as a layout pass. If the element has children and/or
grandchildren, they will all need to complete the layout pass too. This process is intensive
and the fewer passes that can be made, the quicker our Views will render.
As mentioned earlier, we need to be careful to ensure that we do not unnecessarily trigger
additional passes of the layout system, as this can lead to poor performance. This can
occur when adding or removing items to or from a panel, applying transforms on the
elements, or by calling the UIElement.UpdateLayout method, which forces a new layout
pass.
Because of the way that changes to a UI element will invalidate its children and force a new
layout pass, we need to be especially careful when building hierarchical data in code. If we
create the child elements first and then their parent objects and then the parents of those
objects, and so on, then we will incur a huge performance hit, due to the existing child items
being forced to perform multiple layout passes.
In order to address this issue, we need to always ensure that we build our tree from the
top-down, rather than the top-up method just described. If we add the parent element(s)
first and then add their children and their children if any, then we can avoid the additional
layout passes. The performance improvement of using the top-down method is
approximately five times quicker to render, and so is not insignificant. Let’s look at some
further control related performance benefits that we can employ.
Drawing conclusions
When we have a requirement to draw shapes in our UI, such as in our callout window
example in Chapter 7, Creating Visually Appealing User Interfaces, we tend to use the
abstract Shape class, or more accurately, one or more of its derived classes.
The Shape class extends the FrameworkElement class and so, it can make use of the layout
system, be styled, have access to a range of stroke and fill properties and its properties

can be data bound and animated. This makes it easy to use and generally the preferred
method of drawing in WPF applications.
However, WPF also provides lower-level classes that can achieve the same end results, but
more efficiently. The five classes that extend the abstract Drawing class have a much
smaller inheritance hierarchy and as such, have a much smaller memory footprint than their
Shape object-based counterparts.
The two most commonly used classes are the GeometryDrawing class, which is used to
draw geometrical shapes, and the DrawingGroup class, which is used to combine multiple
drawing objects into a single composite drawing.
Additionally, the Drawing class is also extended by the GlyphRunDrawing class, that renders
text, the ImageDrawing class, that displays images and the VideoDrawing class, that
enables us to play video files. As the Drawing class extends the Freezable class, further
efficiency savings can be made by freezing its instances, if they do not need to be modified
afterwards.
There is one other, potentially even more efficient method of drawing shapes in WPF. The
DrawingVisual class does not provide event handling or layout functionality and so, its
performance is improved compared with other drawing methods. However, this is a code
only solution and there is no XAML based DrawingVisual option.
Furthermore, its lack of layout abilities means that in order to display it, we need to create
a class that extends a class that provides layout support in the UI, such as the
FrameworkElement class. To be even more efficient though, we could extend the Visual
class, as that is the lightest weight class that can be rendered in the UI, with the fewest
properties and no events to handle.
This class would be responsible for maintaining a collection of Visual elements to be
rendered, creating one or more DrawingVisual objects to add to the collection and
overriding a property and a method, in order to participate in the rendering process. It could
also optionally provide event handling and hit testing capabilities, if user interaction was
required.
It really depends on what we want to draw. Typically, the more efficient the drawing, the
less flexible it is. For example, if we were just drawing some static clipart, background
image, or perhaps logo, we could take advantage of the more efficient drawing methods,
but if we need our drawing to grow and shrink as the application windows changes size,
then we’ll need to use the less efficient methods that provide more flexibility, or use another
class in addition that provides that functionality.
Let’s look at an example, that creates the same graphical image using each of the three
different drawing methods. We’ll define some smiley face emoticons, starting with the
Shape-based method on the left-hand side, the Drawing object-based method in the center
and the DrawingVisual-based method on the right. Let’s first look at the visual output.

Now, let’s inspect the XAML:
<UserControl
x:Class=“CompanyName.ApplicationName.Views.DrawingView”
xmlns:Controls=
“clr-namespace:CompanyName.ApplicationName.Views.Controls”
xmlns:PresentationOptions=
Width=“450” Height=“150”>
<Grid>
<Grid.Resources>
<RadialGradientBrush x:Key=“RadialBrush” RadiusX=“0.8”
RadiusY=“0.8”
PresentationOptions:Freeze=“True”>
<GradientStop Color=“Orange” Offset=“1.0” />
<GradientStop Color=“Yellow” />
</RadialGradientBrush>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height=“3” />
<RowDefinition Height=“2” />
<RowDefinition Height=“2” />
<RowDefinition Height=“2” />
<RowDefinition Height=“3*” />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Ellipse Grid.RowSpan=“5” Grid.ColumnSpan=“5”
Fill=“{StaticResource RadialBrush}” Stroke=“Black”
StrokeThickness=“5” />
<Ellipse Grid.Row=“1” Grid.Column=“1” Fill=“Black” Width=“20”

HorizontalAlignment=“Center” />
<Ellipse Grid.Row=“1” Grid.Column=“3” Fill=“Black” Width=“20”
HorizontalAlignment=“Center” />
<Path Grid.Row=“3” Grid.Column=“1” Grid.ColumnSpan=“3”
Stroke=“Black”
StrokeThickness=“10” StrokeStartLineCap=“Round”
StrokeEndLineCap=“Round” Data=“M0,10 A10,25 0 0 0 12.5,10”
Stretch=“Fill” HorizontalAlignment=“Stretch” />
</Grid>
<Canvas Grid.Column=“1”>
<Canvas.Background>
<DrawingBrush PresentationOptions:Freeze=“True”>
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing Brush=“{StaticResource
RadialBrush}“>
<GeometryDrawing.Geometry>
<EllipseGeometry Center=“50,50” RadiusX=“50”
RadiusY=“50” />
</GeometryDrawing.Geometry>
<GeometryDrawing.Pen>
<Pen Thickness=“3.5” Brush=“Black” />
</GeometryDrawing.Pen>
</GeometryDrawing>
<GeometryDrawing Brush=“Black”>
<GeometryDrawing.Geometry>
<EllipseGeometry Center=“29.5,33” RadiusX=“6.75”
RadiusY=“8.5” />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush=“Black”>
<GeometryDrawing.Geometry>
<EllipseGeometry Center=“70.5,33” RadiusX=“6.75”
RadiusY=“8.5” />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing>
<GeometryDrawing.Geometry>
<PathGeometry>
<PathGeometry.Figures>
<PathFigure StartPoint=“23,62.5”>
<ArcSegment Point=“77,62.5” Size=“41 41” />
</PathFigure>
</PathGeometry.Figures>
</PathGeometry>
</GeometryDrawing.Geometry>
<GeometryDrawing.Pen>
<Pen Thickness=“7” Brush=“Black”
StartLineCap=“Round”
EndLineCap=“Round” />
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</Canvas.Background>
</Canvas>
<Canvas Grid.Column=“2”>

<Canvas.Background>
<VisualBrush>
<VisualBrush.Visual>
<Controls:SmileyFace />
</VisualBrush.Visual>
</VisualBrush>
</Canvas.Background>
</Canvas>
</Grid>
</UserControl>
The first thing that we can see straight away from this example is that the Shape object-
based method of drawing is far simpler, achieving the same output as the far more verbose
Drawing object-based method in far fewer lines of XAML. Let’s now investigate the code.
After defining the PresentationOptions XML namespace, we declare a
RadialGradientBrush resource and optimize its efficiency, by freezing it using the Freeze
attribute that was discussed earlier in the chapter. Note that if we were planning on using
this control multiple times simultaneously, then we could be even more efficient, by declaring
all of our Brush and Pen objects in the application resources and reference them with
StaticResource references.
We then declare an outer Grid panel, that has two columns. In the left column, we declare
another Grid panel, with five rows and five columns. This inner panel is used to position the
various Shape elements that make up the first smiley face. Note that we use star sizing on
the row definitions of this panel in order to slightly increase the sizes of the top and bottom
rows to better position the eyes and mouth of the face.
Inside the panel, we define an Ellipse object to create the overall shape of the face, fill it
with our brush from the resources and add an outline with a black brush. We then use two
further Ellipse elements filled with the black brush to draw the eyes and a Path element to
draw the smile. Note that we do not fill the Path element, as that would look more like an
open mouth than a smile.
Two other important points to note are that we must set the Stretch property to Fill to get
the Path element to fill the available space that we provide it with and we must set the
StrokeStartLineCap and StrokeEndLineCap properties to Round to produce the nice,
rounded ends of the smile.
We specify the shape that the Path element should be using its Data property and the inline
mini-language that we used previously. Let’s break this value down into the various mini-
language commands now:
M0,10 A10,25 0 0 0 12.5,10
As with the previous example before, we start with the Move command, which is specified
by the M and the following co-ordinate pair and dictates the start point for the line. The
remainder is taken up with the Elliptical Arc command, which is specified by the A and the
following five figures.
In order, the five figures of the Elliptical Arc command relate to the size of the arc, or its x
and y radii, its rotation angle, a bit field to specify whether the angle of the arc should be
greater than 180° or not, another bit field to specify whether the arc should be drawn in a

clockwise or anti-clockwise direction and finally, the end point of the arc.
Full details of this path syntax mini language can be found on the MSDN website. Note that
we could change the bit field for the drawing direction to a 1 to draw a frown instead:
M0,10 A10,25 0 0 1 12.5,10
Now, let’s move onto the second column of the outer Grid panel now. In this column, we
recreate the same smiley face, but using the more efficient Drawing object-based objects.
As they cannot render themselves like the Shape classes and we need to utilize other
elements to do that job for us, we define them inside a DrawingBrush element and use that
to paint the background of a Canvas object.
There are two important things to note here. The first is that we could have used the
DrawingBrush element to paint any class that extends the FrameworkElement class, such as
a Rectangle, or another type of panel.
The second is that as we have frozen the DrawingBrush element using the Freeze attribute,
all of the inner elements that extend the Freezable type will also be frozen. In this case,
that includes the GeometryDrawing objects, the EllipseGeometry and PathGeometry objects
and even the Brush and Pen elements that were used to paint them.
When using a DrawingBrush object to render our drawings, we must define them using its
Drawing property. As we want to build up our image from multiple Drawing-based objects,
we need to wrap them all in a DrawingGroup object.
In order to recreate the overall shape of the face, we start with a GeometryDrawing element
and specify an EllipseGeometry object as its Geometry property value. With this
GeometryDrawing element, we paint the background by setting a reference of our
RadialGradientBrush resource to its Brush property and define a new Pen instance in its
Pen property to specify a stroke for it.
As with all Geometry objects, we specify its dimensions so that they are in scale with each
other, rather than using exact pixel sizes. For example, our View is one hundred and fifty
pixels high, but instead of setting the Center property of this EllipseGeometry object to
seventy-five, which is half of the height, we have set it to fifty.
As the two radii properties are also set to fifty, they remain in scale with the position of the
center and the resulting image is scaled to fit the container that it is rendered in. The scale
that we use is up to our preference. For example, we could divide or multiply all of the co-
ordinates, radii, brush and pen thicknesses in our drawing example by the same amount
and we would end with the same face visual.
Next, we add another GeometryDrawing element with an EllipseGeometry object specified
in its Drawing property for each of the two eyes on the face. These have no stroke and so
have nothing assigned to the Pen property and are colored only using a black Brush set to
their Brush properties. The final GeometryDrawing element hosts a PathGeometry object that
draws the smile on the face.
Note that defining a PathGeometry in XAML is far more verbose than using the path syntax
mini-language. In it, we need to specify each PathFigure element in the PathFigures
collection property, although actually specifying this collection in XAML is optional. In the
case of our smile, we just need to define a single PathFigure element containing an
ArcSegment object.

The StartPoint property of the PathFigure element dictates where the arc should start,
the Size property of the ArcSegment object relates to the size of the arc, or its x and y radii,
while its Point property specifies the end point of the arc.
In order to define round ends for the smile, as we did with the previous smiley face, the Pen
element that we specify for this PathGeometry object must have its StartLineCap and
EndLineCap properties set to the Round member of the PenLineCap enumeration. This
completes the second method of drawing a smiley face.
The third method uses DrawingVisual objects in code internally and results in a Visual
object. As the items in the Children collection of the Grid panel are of type UIElement, we
cannot add our Visual control to it directly. Instead, we can set it to the Visual property of
a VisualBrush element and paint the background of an efficient container, such as a Canvas
control, with it.
Let’s take a look at the code in this SmileyFace class now:
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media;
namespace CompanyName.ApplicationName.Views.Controls
{
public class SmileyFace : Visual
{
private VisualCollection visuals;
public SmileyFace()
{
visuals = new VisualCollection(this);
visuals.Add(GetFaceDrawingVisual());
}
private DrawingVisual GetFaceDrawingVisual()
{
RadialGradientBrush radialGradientBrush =
new RadialGradientBrush(Colors.Yellow, Colors.Orange);
radialGradientBrush.RadiusX = 0.8;
radialGradientBrush.RadiusY = 0.8;
radialGradientBrush.Freeze();
Pen outerPen = new Pen(Brushes.Black, 5.25);
outerPen.Freeze();
DrawingVisual drawingVisual = new DrawingVisual();
DrawingContext drawingContext = drawingVisual.RenderOpen();
drawingContext.DrawEllipse(radialGradientBrush, outerPen,
new Point(75, 75), 72.375, 72.375);
drawingContext.DrawEllipse(Brushes.Black, null,
new Point(44.25, 49.5), 10.125, 12.75);
drawingContext.DrawEllipse(Brushes.Black, null,
new Point(105.75, 49.5), 10.125, 12.75);
ArcSegment arcSegment =
new ArcSegment(new Point(115.5, 93.75), new Size(61.5,
61.5), 0,
false, SweepDirection.Counterclockwise, true);
PathFigure pathFigure = new PathFigure(new Point(34.5,
93.75),

new List<PathSegment>() { arcSegment }, false);
PathGeometry pathGeometry =
new PathGeometry(new List<PathFigure>() { pathFigure });
pathGeometry.Freeze();
Pen smilePen = new Pen(Brushes.Black, 10.5);
smilePen.StartLineCap = PenLineCap.Round;
smilePen.EndLineCap = PenLineCap.Round;
smilePen.Freeze();
drawingContext.DrawGeometry(null, smilePen, pathGeometry);
drawingContext.Close();
return drawingVisual;
}
protected override int VisualChildrenCount
{
get { return visuals.Count; }
}
protected override Visual GetVisualChild(int index)
{
if (index < 0 || index >= visuals.Count)
throw new ArgumentOutOfRangeException();
return visuals[index];
}
}
}
There are several classes that we could have extended our SmileyFace class from, in order
to display it in the UI. As we saw in Chapter 5, Using The Right Controls for The Job, most
UI controls have a rich inheritance hierarchy, with each extended class offering some
particular functionality.
In order to make the most efficient container for our DrawingVisual, we want to extend a
class that enables it to take part in the layout process, but adds as little additional overhead
via unused properties and unrequired event handling as possible. As such, we have chosen
the Visual class, which cannot be used as a UI element directly in the XAML, but can be
displayed as the visual of a VisualBrush element and used to paint a surface with.
To generate one or more DrawingVisual elements in our SmileyFace class, we need to
declare and maintain a VisualCollection instance that will hold the Visual elements that
we want to display. In the constructor, we initialize this collection and add the single
DrawingVisual element that we want to render to it in this example, via the
GetFaceDrawingVisual method.
In the GetFaceDrawingVisual method, we first declare a new version of our RadialBrush
resource using the RadialGradientBrush class and a Pen element and freeze them using
their Freeze methods. Next, we initialize a single DrawingVisual element and access a
DrawingContext object from its RenderOpen method, with which to draw our shape.
We use the DrawingContext object to draw the ellipse that serves as the background for
the face first. It is colored using the frozen Brush and pen elements. Note that as the Visual
class has no Stretch property or concept of size, the dimensions that we use here are
exact device-independent pixel dimensions, rather than relative values, as were used in the
previous drawing methods.

In this example, our smiley faces are one hundred and fifty pixels wide by one hundred and
fifty pixels tall and so the center position will be half of that. Therefore, these exact pixel
values can be calculated by multiplying the relative values from the previous Drawing-based
example by 1.5.
However, we also need to consider the fact that the outline will be drawn half inside the
drawing and half outside. As such, we need to adjust the two radii of this ellipse, reducing
them by half of the outline size. As the pen used for this ellipse has a thickness of 5.25
device-independent pixels, we need to reduce each radii by 2.625.
Next, we call the DrawEllipse method again to draw each of the eyes, passing in a black
brush and no Pen element, along with their newly calculated positions and sizes. For the
smile, we first need to create an ArcSegment element and add that to a collection of type
PathSegment, while initializing a PathFigure object.
We then add the PathFigure object to a collection and pass that to the constructor of the
PathGeometry object to initialize it. Next, we define the Pen that will be used to draw the
smile, ensuring that we set its StartLineCap and EndLineCap properties to the Round
member of the PenLineCap enumeration, as in the previous examples.
We then freeze this Pen object and pass it, along with the PathGeometry object, to the
DrawGeometry method of the DrawingContext object to draw it. Finally, we close the
drawing context using its Close method and return the single DrawingVisual element that
we just created.
While we have now taken care of the code that draws our smiley face, we will not be able
to see anything in the UI yet. In order to participate in the rendering process, we need to
override a couple of members from the Visual class, the VisualChildrenCount property
and the GetVisualChild method.
When overriding these members, we simply need to inform the Visual class of the visuals
that we want it to render for us. As such, we simply return the number of items in our
internal VisualCollection object from the VisualChildrenCount property and return the
item in the collection that relates to the specified index input parameter from the
GetVisualChild method.
In this example, we have added a check for invalid values from the index input parameter,
although this shouldn’t ever occur if we output the correct number of items from the
VisualChildrenCount property in the first place.
So now, we have seen three different drawing methods for creating the same visual output,
with each being more efficient than the previous. However, apart from the efficiency
differences, we should also be aware of the differences in these drawing methods when it
comes to manipulation and versatility of the elements.
As an example, let’s adjust the Width of our DrawingView class, set its ClipToBounds
property to true and see its new output.
Width=“225” Height=“150” ClipToBounds=“True”>
Let’s now run the application again and see the output:

As we can see from the preceding image, these drawing methods behave differently when
resized. The first method is redrawn at the current size and the thickness of each drawn line
remains the same, even though the width of this face has been narrowed by the space
provided to it from the parent Grid panel.
However, the second and third smiley faces actually look like a squashed image, where the
thickness of each line is no longer static; the more vertical the line is, the thinner it now
becomes. The overall width of these faces have also been adjusted by the parent Grid
panel.
The third face however, has only been scaled by the VisualBrush object that is used to
display it. If instead of extending the Visual class, we had wanted to derive from the
UIElement class, to utilize some of its functionality, or perhaps to enable us to display our
SmileyFace control directly in the XAML, then we would see a different output. Let’s make a
slight adjustment to our class declaration:
public class SmileyFace : UIElement
Let’s also display it directly in the XAML now, replacing the Canvas and VisualBrush that
previously displayed it:
<Controls:SmileyFace Grid.Column=“2” />
Now, if we run the application again and see the output, it will look very different:
Because we specified exact values for our drawing, our SmileyFace control does not extend
any class that would enable resizing or scaling and we no longer have the VisualBrush to
resize it, the drawing remains exactly as it would be at full size, except that it now no longer
fits into the space provided to it from the parent Grid panel.
In order to build the ability to draw the shape at different sizes into our class, we’ll need to
derive it from a class that provides us with additional properties and functionality. The

FrameworkElement class supplies us with both dimension properties that we can use to
draw our shape at the required size and a Loaded event that we can use to delay the
construction of our shape until the relevant size has been calculated by the layout system.
Let’s see the changes that we’d need to make to achieve this:
public class SmileyFace : FrameworkElement
{
public SmileyFace()
{
visuals = new VisualCollection(this);
Loaded += SmileyFace_Loaded;
}
private void SmileyFace_Loaded(object sender, RoutedEventArgs e)
{
visuals.Add(GetFaceDrawingVisual());
}
private DrawingVisual GetFaceDrawingVisual()
{
DrawingVisual drawingVisual = new DrawingVisual();
DrawingContext drawingContext = drawingVisual.RenderOpen();
drawingContext.DrawEllipse(radialGradientBrush, outerPen,
new Point(ActualWidth / 2, ActualHeight / 2), (ActualWidth -
outerPen.Thickness) / 2, (ActualHeight - outerPen.Thickness)
/ 2);
drawingContext.DrawEllipse(Brushes.Black, null, new Point(
ActualWidth / 3.3898305084745761, ActualHeight /
3.0303030303030303),
ActualWidth / 14.814814814814815, ActualHeight /
11.764705882352942);
drawingContext.DrawEllipse(Brushes.Black, null, new Point(
ActualWidth / 1.4184397163120568, ActualHeight /
3.0303030303030303),
ActualWidth / 14.814814814814815, ActualHeight /
11.764705882352942);
ArcSegment arcSegment = new ArcSegment(new Point(ActualWidth /
1.2987012987012987, ActualHeight / 1.6), new Size(ActualWidth
/
2.4390243902439024, ActualHeight /
2.4390243902439024), 0,
false,
SweepDirection.Counterclockwise, true);
PathFigure pathFigure = new PathFigure(new Point(ActualWidth /
4.3478260869565215, ActualHeight / 1.6), new
List<PathSegment>() {
arcSegment }, false);
PathGeometry pathGeometry =
new PathGeometry(new List<PathFigure>() { pathFigure });
return drawingVisual;
}
}

The first change is that we need to move the call to generate the shape from the
constructor to the SmileyFace_Loaded handling method. If we had not moved this, our
shape would have no size, because the ActualWidth and ActualHeight properties that are
used to define its size would not have been set by the layout system at that time.
Next, in the GetFaceDrawingVisual method, we need to replace the hardcoded values with
divisions of the control’s dimensions. The ellipse that draws the whole face is simple to
calculate, with a position of half the width and height of the control and radii of half of the
width and height of the control minus half of the thickness of the Pen element that draws its
outline.
However, if you were wondering where all of the remaining long decimal divisor values
came from, the answer is basic mathematics. The original drawing was one hundred and
fifty pixels wide by one hundred and fifty pixels tall and so we can divide this by the various
position and sizes of the drawn lines from the previous example.
For example, the ellipse that draws the first eye was previously centered with an X position
of 44.25, so to calculate our required width divisor, we simply divide 150 by 44.25, which
equals 3.3898305084745761. Therefore, when the control is provided with 150 pixels of
space, it will draw the left eye at an X position of 44.25 and it will now scale correctly at all
other sizes.
The divisors for each position and size of the drawn shapes were all calculated using this
method, to ensure that they would be sized appropriately for the space provided to our
control. Note that we could have altered the brush and pen thicknesses likewise, but have
opted not to do so in this example for brevity.
When running this example now, we again have a slightly different output:
Now, the first and third faces look more similar, with the thicknesses of their drawn lines
being static and unchanging along their length, unlike the second face. So, we see that we
have many options when it comes to creating custom drawings and we need to balance the
need for efficiency with the ease of use of the drawing method and also take the use of the
resulting image into consideration.
Before moving onto the next topic in this chapter, there are a few further efficiency savings
that we can make when drawing complex shapes. If our code uses a large number of
PathGeometry objects, then we can replace them by using a StreamGeometry object instead.
The StreamGeometry class is specifically optimized to handle multiple path geometries and
shows better performance than can be attained from using multiple PathGeometry

instances. In fact, we have already been using the StreamGeometry class inadvertently, as
that is what is used internally when the binding path syntax mini-language is parsed by the
XAML reader.
It can be thought of in a similar way to the StringBuilder class, in that it is more efficient at
drawing complex shapes than using multiple instances of the PathGeometry class, but that it
has some overhead and so only benefits us when replacing a fair number of them.
Finally, rather than display our DrawingVisual using a VisualBrush, which is refreshed
during each layout pass, if our drawings are never to be manipulated in the UI, it is even
more efficient to create actual images from them and display those instead.
The RenderTargetBitmap class provides a simple way for us to create images from Visual
instances, using its Render method. Let’s see an example of this:
using System.IO;
using System.Windows.Media;
using System.Windows.Media.Imaging;
RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap(
(int)ActualWidth, (int)ActualHeight, 96, 96,
PixelFormats.Pbgra32);
renderTargetBitmap.Render(drawingVisual);
renderTargetBitmap.Freeze();
PngBitmapEncoder image = new PngBitmapEncoder();
image.Frames.Add(BitmapFrame.Create(renderTargetBitmap));
using (Stream stream = File.Create(filePath))
{
image.Save(stream);
}
We start by initializing a RenderTargetBitmap object with the required dimensions, resolution
and pixel format of the image to create. Note that the Pbgra32 member of the static
PixelFormats class specifies a pixel format that follows the sRGB format, using 32 bit per
pixel, with each of the four alpha, red, green and blue channels receiving 8 bits each per
pixel.
Next, we pass our DrawingVisual element, or any other element that extends the Visual
class, to the Render method of the RenderTargetBitmap class to render it. To make the
operation more efficient still, we then call its Freeze method to freeze the object.
In order to save a PNG image file, we first initialize a PngBitmapEncoder object and add the
renderTargetBitmap variable to its Frames collection via the Create method of the
BitmapFrame class. Finally, we initialize a Stream object using the File.Create method,
passing in the desired file name and path, and call its Save method to save the file to the
computer’s hard drive. Alternatively, the JpegBitmapEncoder class can be used to create a
JPG image file.
Let’s now move on to find ways of using images more efficiently.
Imaging more efficiently
When an image is displayed in a WPF application, it is loaded and decoded at its full size
by default. If your application displays a number of thumbnails from the original images,

then you can gain enhanced performance by copying your full size images and resizing them
to the correct size for the thumbnails, rather than letting WPF do it for you.
Alternatively, you can request that WPF decodes your images to the size required by the
thumbnails, although if you want to display the full size images, you would really need to
decode each full size image separately. Let’s see how we can achieve this using a
BitmapImage object as the source for an Image control:
<Image Width=“64”>
<Image.Source>
<BitmapImage DecodePixelWidth=“64”
UriSource=“pack://application:,,,/
CompanyName.ApplicationName;component/Images/Image1.png” />
</Image.Source>
</Image>
The important part of this example is the DecodePixelWidth property of the BitmapImage
class, which specifies the actual size of the image to decode to. In this example, this would
result in a smaller memory footprint as well as faster rendering.
Note that if the DecodePixelHeight and DecodePixelWidth properties of the BitmapImage
class are both set, a new aspect ratio will be calculated from their values, but if only one of
these properties is set, then the image’s original aspect ratio will be used. It is therefore
customary to only set one of these properties in order to decode to a different size from the
original, while maintaining its aspect ratio.
Normally, when images are used in a WPF application, they are all cached into memory at
load time. Another benefit that can be gained if using code in the aforementioned scenario
is to set the CacheOption property of the BitmapImage class to the OnDemand enumeration
member, which postpones the caching of the relevant image until the image is actually
requested to be displayed.
This can save a significant amount of resources at load time, although each image will take
a tiny bit longer to display the first time they are displayed. Once the image is cached
however, it will work in exactly the same way as images created in the default way.
There is one additional property in the BitmapImage class that can be used to improve the
performance when loading multiple image files. The CreateOptions property is of
enumeration type BitmapCreateOptions and enables us to specify initialization options that
relate to the loading of images. This enumeration can be set using bitwise combinations as
it specifies the FlagsAttribute attribute in its declaration.
The DelayCreation member can be used to delay the initialization of each image until it is
actually required, thereby speeding up the process of loading the relevant View, while
adding a tiny cost to the process of requesting each image when it is actually required.
This would benefit a photo gallery type application, for example, where the initialization of
each full size image could be delayed until the user clicks on the appropriate thumbnail. It is
only at that point that the image would be created, but as there would only be a single
image to create at that point, the initialization time would be negligible.
While it is possible to set more than one of these members to the CreateOptions property
using the bitwise OR operator (|), care should be taken not to also set the
PreservePixelFormat member, unless specifically required, as that can result in lower

performance. When it is not set, the system will chose the pixel format with the best
performance by default. Let’s see a short example:
private Image CreateImageEfficiently(string filePath)
{
Image image = new Image();
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.CacheOption = BitmapCacheOption.OnDemand;
bitmapImage.CreateOptions = BitmapCreateOptions.DelayCreation;
bitmapImage.UriSource = new Uri(filePath, UriKind.Absolute);
bitmapImage.EndInit();
image.Source = bitmapImage;
return image;
}
When creating images in code, we need to initialize an instance of the BitmapImage class to
use as the source for the actual Image object that we will be displaying in the UI. When
doing so, we need to call its BeginInit method before making changes to it and call its
EndInit method afterwards. Note that all changes made after initialization will be ignored.
During initialization, we set the CacheOption property to the OnDemand member and the
CreateOptions property to the DelayCreation member. Note that we do not set the
DecodePixelWidth or DecodePixelHeight properties here, because this code example is
setup for initializing the full size images in our gallery example.
Also note that in this particular example, we initialize the Uri object using an absolute file
path, by passing the Absolute member of the UriKind enumeration into the constructor. If
you prefer to work with relative file paths, you can change this line to specify a relative file
path by passing the Relative member to the constructor instead:
bitmapImage.UriSource = new Uri(filePath, UriKind.Relative);
Now that we’ve seen some tips on how to display our images more efficiently, let’s
investigate how we might do the same for our application’s textual output.
Enhancing the performance of textual output
WPF provides similar options for creating text as it does for drawing shapes; the more
versatile the output method, the easier it is to use, but the less efficient it is and vice versa.
The vast majority of us opt for the simplest, but least efficient method of using the high-level
TextBlock or Label elements.
While this doesn’t typically cause us any problems when used in typical forms, there is
definitely room for improvement when displaying thousands of text blocks in a data grid, or
other collection control. If we require formatted text, we can utilize the more efficient
FormattedText object, otherwise we can use the lowest level method and the most efficient
Glyphs elements.
Let’s see an example:
<UserControl x:Class=“CompanyName.ApplicationName.Views.TextView”
xmlns:Controls=
“clr-namespace:CompanyName.ApplicationName.Views.Controls”

Height=“250” Width=“325”>
<Grid ShowGridLines=“True”>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Label Content=“Quite Efficient” FontFamily=“Times New Roman”
FontSize=“50” FontWeight=“Bold” FontStyle=“Italic”
Foreground=“Red” Margin=“10,0,0,0” Padding=“0” />
<TextBlock Grid.Row=“1” Text=“More Efficient”
FontFamily=“Times New Roman” FontSize=“50” FontWeight=“Bold”
FontStyle=“Italic” Foreground=“Black” Margin=“10,0,0,0” />
<Controls:FormattedTextOutput Grid.Row=“2” Text=“More
Efficient” />
<Glyphs Grid.Row=“3” UnicodeString=“Most Efficient”
FontUri=“C:\WINDOWS\Fonts\timesbi.TTF”
FontRenderingEmSize=“50”
Fill=“Black” OriginX=“10” OriginY=“45” />
</Grid>
</UserControl>
Here we have a View that has a Grid panel with four rows. The first row holds a Label
control, which although fairly efficient, is the least efficient of the textual output methods
shown here and as we’ll see soon, should only be used in very specific circumstances. On
it, we specify the FontFamily, FontSize, FontWeight, FontStyle and Foreground properties
to define how its text should look.
The second row contains a TextBlock element, which is slightly more efficient and like the
Label element, we specify the FontFamily, FontSize, FontWeight and FontStyle and
Foreground properties on it directly. It’s worth noting that to result in the same visual output,
we don’t need to set its Padding property to 0, which was required with the Label control.
In the third row, we have a custom FormattedTextOutput control that uses a FormattedText
object internally and is slightly more efficient still. As we’ll see shortly, we need to specify
the relevant properties of this text object in code.
Finally, we see a Glyphs element in the fourth row and this represents the most efficient
method of outputting text in a WPF application. Note that when using this method of textual
output, we don’t specify a font family by name, but instead set an exact font file path to its
FontUri property.
As we want to match the bold italic version of the Times New Roman font, we specifically
need to set the file path to that exact file. Therefore, we need to specify the timesbi.ttf
file, rather than the normal times.ttf version. Other than setting the font size to the
FontRenderingEmSize property and the margin to the OriginX and OriginY properties, this
class is fairly self-explanatory.
Before continuing, let’s first see the visual output of this View:

Let’s now take a look at the code inside the FormattedTextOutput class:
using System.Globalization;
using System.Windows;
using System.Windows.Media;
namespace CompanyName.ApplicationName.Views.Controls
{
public class FormattedTextOutput : FrameworkElement
{
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register(nameof(Text), typeof(string),
typeof(FormattedTextOutput), new FrameworkPropertyMetadata(
string.Empty,
FrameworkPropertyMetadataOptions.AffectsRender));
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
protected override void OnRender(DrawingContext drawingContext)
{
FormattedText formattedText = new FormattedText(Text,
CultureInfo.GetCultureInfo(“en-us”),
FlowDirection.LeftToRight,
new Typeface(“Times New Roman”), 50, Brushes.Red);
formattedText.SetFontStyle(FontStyles.Italic);
formattedText.SetFontWeight(FontWeights.Bold);
drawingContext.DrawText(formattedText, new Point(10, 0));
}
}
}
The FormattedTextOutput class is a fairly simple affair, with a single Dependency Property
and its associated CLR wrapper and a single overridden base class method. One very
important point to note is our use of the AffectsRender member of the
FrameworkPropertyMetadataOptions enumeration to specify that changes to this property

needs to cause a new rendering pass.
Typically, the Text property will be updated from any data binding after the OnRender
method is called by the UIElement base class. Without specifying this option, our class will
never output any data bound values. By specifying this option, we are in fact, telling the
Framework to call the OnRender method again each time this property value changes.
In the overridden OnRender method, we first initialize a FormattedText object with basic
properties, such as the text to render, the current culture and the color, size and type of the
font to use. Additional style properties can be set using the various set methods that the
class exposes. Finally, we call the DrawText method of the DrawingContext object specified
by the drawingContext input parameter, passing in the FormattedText object and the
position to render it.
Note that we can use data binding with all of these text rendering methods, so let’s update
our previous example now to demonstrate:
<Label Content=“{Binding Text}” FontFamily=“Times New Roman”
FontSize=“50” FontWeight=“Bold” FontStyle=“Italic”
Foreground=“Red”
Margin=“10,0,0,0” Padding=“0” />
<TextBlock Grid.Row=“1” Text=“{Binding Text}”
FontFamily=“Times New Roman” FontSize=“50” FontWeight=“Bold”
FontStyle=“Italic” Foreground=“Red” Margin=“10,0,0,0” />
<Controls:FormattedTextOutput Grid.Row=“2” Text=“{Binding Text}” />
<Glyphs Grid.Row=“3” UnicodeString=“{Binding Text}” FontUri=
“C:\WINDOWS\Fonts\timesbi.TTF” FontRenderingEmSize=“50”
Fill=“Black” OriginX=“10” OriginY=“45” />
For this example, we can simply hardcode a value in our View Model.
namespace CompanyName.ApplicationName.ViewModels
{
public class TextViewModel : BaseViewModel
{
public string Text { get; set; } = “Efficient”;
}
}
Although we can data bind when using all of these textual output methods, there are some
caveats to be aware of. We’ve just learnt of one relating to the required metadata of the
Text property in our custom FormattedTextOutput class and there is another relating to the
Glyphs class.
It has a requirement that the UnicodeString property cannot be empty if the Indicies
property, which represents an alternative method of providing the text to render, is also
empty. Unfortunately, because of this requirement, attempting to data bind to the
UnicodeString property as we did in our extended example will result in a compilation error:
Glyphs Indices and UnicodeString properties cannot both be empty.
To address this issue, we can simply provide a value for the FallbackValue property of the
Binding class, so that the Glyphs class can rest assured that even if there is no data bound
value, its UnicodeString property will have a non-empty value. Note that setting the

FallbackValue property to an empty string will result in the same error being raised.
<Glyphs Grid.Row=“3” UnicodeString=“{Binding Text,
FallbackValue=‘Data
Binding Not Working’}” FontUri=“C:\WINDOWS\Fonts\timesbi.TTF”
FontRenderingEmSize=“50” Fill=“Black” OriginX=“10” OriginY=“45”
/>
There is one further issue regarding data binding, but this time, it involves the Content
property of the Label class. Because strings are immutable, each time a data bound value
updates the Content property, the previous string will be discarded and replaced with the
new one.
Furthermore, if the default ContentTemplate element is used, it will generate a new
TextBlock element and discard the previous element each time the property string is
replaced. As a result, updating a data bound TextBlock is approximately four times quicker
than updating a Label. Therefore, if we need to update our data bound text values, we
should not use a Label control.
In fact, each method of rendering text has its own purpose. The Label control should
specifically be used to label text fields in a form and in doing so, we can take advantage of
its access key functionality and its ability to reference a target control. The TextBlock
element is a general purpose text output method that should be used for the majority of the
time.
The FormattedText object should really only be used when we specifically want to format
some text in a particular way. It provides the ability to output text with a wide range of
effects, such as being able to paint the stroke and fill of the text independently and to
format particular ranges of characters within the rendered text string.
The Glyphs class extends the FrameworkElement class directly and is therefore extremely
light-weight and should be utilized when we need to recreate our text output more efficiently
than we can using the alternative methods. Although the FormattedText class can make use
of lower, core level classes to render its output, the most efficient way to render text is to
use Glyphs objects.
Liking the linking
As we have already seen, each UI element that we use in our Views takes time to render.
Simply put, the fewer elements that we use, the quicker the View will be displayed. Those
of us that have used Hyperlink elements in our Views will already be aware that we cannot
display them on their own, but instead have to wrap them inside a TextBlock element.
However, as each Hyperlink element is self-contained, with its own navigation URI, content
and property options, we can actually display more than one of them in a single TextBlock
element. This will reduce the render time and so, the more TextBlock elements that we can
remove, the quicker it will become. Let’s see an example:
<ListBox ItemsSource=“{Binding Products}” FontSize=“14”
HorizontalContentAlignment=“Stretch”>
<ListBox.ItemTemplate>
<DataTemplate DataType=“{x:Type DataModels:Product}“>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />

<ColumnDefinition Width=“Auto” />
<ColumnDefinition Width=“Auto” />
</Grid.ColumnDefinitions>
<TextBlock Text=“{Binding Name}” />
<TextBlock Grid.Column=“1”
Text=“{Binding Price, StringFormat=C}” Margin=“10,0” />
<StackPanel Grid.Column=“2” TextElement.FontSize=“14”
Orientation=“Horizontal”>
<TextBlock>
<Hyperlink Command=“{Binding ViewCommand,
RelativeSource={RelativeSource
AncestorType={x:Type Views:TextView}}}”
CommandParameter=“{Binding}”>View</Hyperlink>
</TextBlock>
<TextBlock Text=” | “ />
<TextBlock>
<Hyperlink Command=“{Binding EditCommand,
RelativeSource={RelativeSource
AncestorType={x:Type Views:TextView}}}”
CommandParameter=“{Binding}”>Edit</Hyperlink>
</TextBlock>
<TextBlock Text=” | “ />
<TextBlock>
<Hyperlink Command=“{Binding DeleteCommand,
RelativeSource={RelativeSource
AncestorType={x:Type Views:TextView}}}”
CommandParameter=“{Binding}”>Delete</Hyperlink>
</TextBlock>
</StackPanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Here, we have a collection of Product objects that are data bound to a ListBox, with each
item displaying its name, price and three commands in the form of Hyperlink objects. Let’s
see what this looks like before continuing:
Focusing on the links now, our example uses nine UI elements per item to render these
three links. The StackPanel element keeps them altogether, with each Hyperlink object
having its own TextBlock element and a further two TextBlock elements to display the pipe
separator characters.
The Hyperlink objects are data bound to commands in the View Model and the
CommandParameter property is data bound to the whole Product object that is set as the
data source for each item. In this way, we will have access to the relevant Product instance
in the View Model when a link is clicked.
While there is nothing wrong with this XAML, if we need to be more efficient, then we can
replace everything inside the StackPanel and the panel itself with the following TextBlock
element:

<TextBlock Grid.Column=“2” TextElement.FontSize=“14”
Foreground=“White”>
<Hyperlink Command=“{Binding ViewCommand, RelativeSource={
RelativeSource AncestorType={x:Type Views:TextView}}}”
CommandParameter=“{Binding}”>View</Hyperlink>
<Run Text=” | “ />
<Hyperlink Command=“{Binding EditCommand, RelativeSource={
RelativeSource AncestorType={x:Type Views:TextView}}}”
CommandParameter=“{Binding}”>Edit</Hyperlink>
<Run Text=” | “ />
<Hyperlink Command=“{Binding DeleteCommand, RelativeSource={
RelativeSource AncestorType={x:Type Views:TextView}}}”
CommandParameter=“{Binding}”>Delete</Hyperlink>
</TextBlock>
As you can see, we now host all three Hyperlink objects inside a single TextBlock element
and have replaced the two TextBlock elements that displayed the pipe characters with Run
objects. Using the Run class is moderately more efficient than using one TextBlock element
inside another.
Now, we need only render six elements per item to produce the links, including using two
more efficient elements, rendering three elements fewer per item. However, if we had a
thousand products, we would end up rendering three thousand fewer UI elements, with two
thousand more efficient replacements, so it is easy to see how this can soon add up to
some real efficiency savings.
In this example, we could make further improvements, by simply removing the line under
each link. Bizarrely, we can save up to twenty-five percent of the rendering time taken to
render our Hyperlink elements if we remove their underlines. We can do this by setting
their TextDecoration s property to None:
<Hyperlink … TextDecorations=“None”>View</Hyperlink>

Data binding
There are also a number of performance improvements that we can make when data
binding in our applications. The simplest of which can be obtained by simply setting the
Binding.Mode property correctly. In order to make data binding possible, the Framework
attaches handlers to listen out for changes to our data bound properties.
For two-way bindings, event handlers will be attached to the PropertyChanged event of the
INotifyPropertyChanged interface to listen to changes in our data model objects or View
Models and to various other XxxChanged events in the relevant binding target controls to
listen to UI-based property changes.
When we only require one way bindings, we can save some computing resources by setting
the Mode property of the Binding class to the appropriate member of the BindingMode
enumeration. If you remember, when a data bound property is for display purposes only, we
should set its Mode property to OneWay and when we have no need to update an editable
field from the View Model, we should set its Mode property to the OneWayToSource member.
In doing this, we cut down the number of event handlers listening for changes and therefore
free up resources to be used where they are actually needed. Once again, the effect of
doing this on one binding alone would be negligible, but if we practice this on every relevant
binding, then the efficiency improvement will start to make a difference.
Another good practice to get into is to set the FallbackValue property of the Binding class
on each binding that we declare. As mentioned in Chapter 4, Becoming Proficient with Data
Binding, doing this will stop the WPF Framework from performing a lookup of the default
value of the target Dependency Property when there are data binding errors and will
prevent trace statements from being generated and output.
Likewise, setting the TargetNullValue property is similar to setting the FallbackValue
property in that it is slightly more efficient than not setting it. Again, doing this on a single
binding will have a negligible effect, yet if we do this on every binding, it will free up CPU
cycles for rendering or other required processes.
In fact, the best binding related way to increase the performance of our applications is to
simply fix any data binding errors that we may have. Each time a binding cannot be
resolved, the Framework will perform a number of checks, using up valuable resources, as
mentioned previously in this section. Therefore, keeping the Output window free of binding
errors is a must when it comes to performance.
Registering Dependency Properties
As we saw in the Using the right controls for performance section earlier in this chapter,
we need to be careful when setting the metadata for our Dependency Properties.
Incorrectly specifying the framework metadata while registering our Dependency Properties
can lower performance by forcing the layout system to unnecessarily perform additional
layout passes.
In particular, we need to be careful when specifying any of the AffectsMeasure,
AffectsArrange, AffectsParentMeasure, AffectsParentArrange, or the AffectsRender
members of the FrameworkPropertyMetadataOptions enumeration and ensure that they are

actually required.
Likewise, if we specify the Inherits member of the FrameworkPropertyMetadataOptions
enumeration when registering our Dependency Property, we are effectively increasing the
length of time that invalidation will take on the property. As such, we should ensure that this
particular metadata member is only used when it is really necessary.
One last metadata option that can improve the performance of the application is the
SubPropertiesDoNotAffectRender member. If the type of our Dependency Property is a
reference type, we can specify this enumeration member to stop the layout system from
checking for changes to all sub properties of the object, which it would otherwise do by
default.
While we may need to call the OverrideMetadata method of the DependencyProperty class
to override the metadata of the pre-existing properties in the .NET Framework, this comes
with a small performance impact. When setting metadata for our own custom Dependency
Properties, we should always use the appropriate Register or RegisterAttached method
to specify our requirements, as this offers far better performance.
Likewise, when registering our custom Dependency Properties, we should also set their
default values using the relevant Register or RegisterAttached method as they are
created, rather than initializing each instance individually in a constructor, or by using some
other method.
Binding to collections
As you are most probably aware, when dealing with collections that will be updated in a
WPF application, we tend to prefer using the generic ObservableCollection<T> class. The
reason for this is because this class implements the INotifyCollectionChanged interface,
which notifies listeners of changes to the collection, such as adding, removing or clearing
items.
What we may not realize is the incredible performance improvement that we get from using
this class to hold our data collections. When comparing this with the generic List<T> class
for example, we note that it does not automatically raise any collection changed event. In
order to enable the View to display the updated collection, we need to reset it as the
ItemsSource property value of the relevant collection control.
However, each time that the ItemsSource property is set, the data bound collection control
will clear its current list of items and completely regenerate them again, which can be a time
consuming process. So, to add a single item to an ObservableCollection<T> takes
approximately 20 milliseconds to render, but to reset the ItemsSource property value could
take over 1.5 seconds.
However, if our collection is immutable and we will not be altering it in any way, we do not
need to use the generic ObservableCollection<T> class, as we have no need for its
change handlers. Rather than wasting resources on unused change handlers, we can use a
different type of collection class.
While there is not a preferred type of collection to use when data binding immutable
collections to UI controls, we should try to avoid using the IEnumerable class as the
collection container. This type cannot be used directly by the ItemsControl class and when

it is used, the WPF Framework will generate a generic IList<T> collection to wrap the
IEnumerable instance and this can also negatively affect performance.
In the next few sections, we’ll see other ways that we can display large collections
efficiently.

Shrinking data objects
Quite often, our applications will have fairly sizable data objects, with dozens, or even
hundreds of properties. If we were to load all of the properties for each data object when
we have thousands of them, our application would slow down and possibly even run out of
memory.
We might think that we can save on RAM by simply not populating all of the property
values, but if we use the same classes, we’ll soon find that even the default or empty values
for these properties may consume too much memory. In general and with a few exceptions,
unset properties take the same amount of RAM as set properties.
If our data model object has a very large number of properties, one solution would be to
break it down into much smaller pieces. For example, we could create a number of smaller,
sub product classes, such as ProductTechnicalSpecification, ProductDescription,
ProductDimension, ProductPricing, etc.
Rather than building one giant View to edit the whole product, we could then provide a
number of smaller Views, perhaps even accessible from different tabs within the same
View. In this way, we would be able to just load the ProductDescription objects for the
user to select from and then load the individual sections of the product in each sub View.
There is a significant performance increase to be gained by this method, as binding to a
single object with a great many properties can take up to four times longer than binding to a
great many objects with fewer properties.
One alternative to breaking our data objects into smaller pieces would be to use the
concept of thin data objects. For example, imagine that our Product class had dozens of
properties and that we had thousands of products. We could create a ThinProduct class,
that contains only the properties that would be used to identify the full data object to load
when selected and those displayed in the product collection.
In this case, we might simply need two properties in our ThinProduct class, a unique
identification property and a display name property. In this way, we can reduce the memory
footprint of our products by a factor of ten or even more. This means that they can be
loaded from the database and displayed in a fraction of the time of the full Product objects.
In order to facilitate easy transferal between the Product and ThinProduct classes, we can
add constructors into each class that accepts the other type and updates the relevant
properties.
using System;
namespace CompanyName.ApplicationName.DataModels
{
public class ThinProduct : BaseDataModel
{
private Guid id = Guid.Empty;
private string name = string.Empty;
public ThinProduct(Product product)
{
Id = product.Id;
Name = product.Name;

}
public Guid Id
{
get { return id; }
set { if (id != value) { id = value;
NotifyPropertyChanged(); } }
}
public string Name
{
get { return name; }
set { if (name != value) { name = value;
NotifyPropertyChanged(); } }
}
public override string ToString()
{
return Name;
}
}
}
The properties in this ThinProduct class basically mirror those from the Product class that
we saw earlier, but only the ones that are used to identify each instance. A constructor is
added that takes an input parameter of type Product to enable easy transferal between the
two. A similar constructor is added to the Product class, but takes an input parameter of
type ThinProduct.
public Product(ThinProduct thinProduct) : this()
{
Id = thinProduct.Id;
Name = thinProduct.Name;
}
The idea is that we have a View Model that displays a large number of products and in
code, we actually load a large number of these much lighter ThinProduct instances. When
the user selects one of the products to view or edit, we use the identification number of the
selected item to then load the full Product object that relates to that identifier.
Given a base collection of these ThinProduct instances in a property named Products, we
could achieve this as follows. First, let’s bind our collection to a ListBox control:
<ListBox ItemsSource=“{Binding Products}”
SelectedItem=“{Binding Products.CurrentItem}” … />
When the user selects a product from the list, the collection’s CurrentItem property will
hold a reference to the selected item. If we attach a handler to the collection’s
CurrentItemChanged delegate when it is first loaded, we can be notified when the item is
selected. At that point, we can load the full Product object using the identifier from the
selected ThinProduct instance and output the associated feedback to the user.
private void Products_CurrentItemChanged(ThinProduct oldProduct,
ThinProduct newProduct)
{
GetDataOperationResult<Product> result =
await Model.GetProductAsync(Products.CurrentItem.Id);

if (result.IsSuccess) Product = result.ReturnValue;
else FeedbackManager.Add(result, false);
}
In the next section, we’ll find out how we can display our large collections more efficiently,
using collection controls, rather than having to break up our large classes into smaller
classes, or create associated thin data objects.

Virtualizing collections
When we display large numbers of items in our collection controls, it can negatively affect
the application’s performance. This is because the layout system will create a layout
container, such as a ComboBoxItem in the case of a ComboBox for example, for every item in
the data bound collection. As only a small subset of the complete number of items is
displayed at any one time, we can take advantage of virtualization to improve the situation.
UI virtualization defers the generation and layout of these item containers until each item is
actually visible in the relevant collection control, often saving on large amounts of resources.
We can take advantage of virtualization without doing anything at all if we use ListBox or
ListView controls to display our collections, as they use it by default.
Virtualization can also be enabled in ComboBox, ContextMenu and TreeView controls,
although it will have to be done manually. When using a TreeView control, we can enable
virtualization by simply setting the VirtualizingStackPanel.IsVirtualizing attached
property to True on it.
<TreeView ItemsSource=“{Binding Items}”
VirtualizingStackPanel.IsVirtualizing=“True” />
For other controls that use the StackPanel class internally, such as the ComboBox and
ContextMenu controls, we can enable virtualization by setting an ItemsPanelTemplate
element hosting an instance of the VirtualizingStackPanel class with its IsVirtualizing
property set to True to its ItemsPanel property:
<ComboBox ItemsSource=“{Binding Items}”>
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel IsVirtualizing=“True” />
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>
</ComboBox>
Apart from setting the IsVirtualizing property to False, there are a few other reasons
why UI virtualization may not work. One case is when item containers have manually been
added to an ItemsControl object or one of its derived controls. Another case is when the
item containers are of different types.
The final reason why virtualization may not work is not so obvious and relates to the
CanContentScroll property of the ScrollViewer class. This is an interesting property that
specifies whether the ScrollViewer in a collection control will scroll its items in logical units,
or physical units. The default value is false, which smoothly scrolls in terms of physical
units.
Physical units relate to the device-independent pixels that WPF works with, while logical
units relate to the widths or heights of the collection items, depending on the orientation of
the control. As the default value of the CanContentScroll property is false, this will need to
be set to True to enable virtualization, so that scrolling is performed item by item and not
pixel by pixel.
When virtualization is employed in a collection control that extends the ItemsControl class
and the user scrolls, new item containers are created for the newly visible items and the

containers for the items that are no longer visible are disposed of.
In version 3.5 of the .NET Framework, an optimization of the virtualization system was
introduced. Container recycling enables the collection control to reuse the item containers,
instead of creating new ones and disposing of old ones as the user scrolls. This offers an
additional performance benefit and can be enabled by setting the VirtualizationMode
Attached Property to a value of Recycling.
<TreeView ItemsSource=“{Binding Items}”
VirtualizingStackPanel.IsVirtualizing=“True” />
VirtualizingStackPanel.VirtualizationMode=“Recycling” />
One further optimization that WPF provides us with is deferred scrolling. Normally, scrolling
in a collection control continuously updates the UI. However, if our data items or their item
containers have several layers of visuals that define them and scrolling is slow, we can opt
to defer the UI update until scrolling has finished.
In order to enable deferred scrolling on a collection control, we need to set the
ScrollViewer.IsDeferredScrollingEnabled Attached Property to True. Although we don’t
generally use ScrollViewer elements in XAML directly, we can also attach this property to
collection controls that host a ScrollViewer element in their control templates.
<ListBox ItemsSource=“{Binding Items}”
ScrollViewer.IsDeferredScrollingEnabled=“True” />

Handling events
One of the most common causes of memory leaks appearing in an application is the failure
to remove event handlers once objects are no longer needed. When we attach an event
handler to an object’s event in the usual way, we are effectively passing that object a
reference to the handler and creating a hard reference to it.
When the object is no longer needed and could otherwise be disposed of, the reference in
the object that raises the event will prevent that from occurring. This is because the
garbage collector cannot collect an object that can be accessed from any part of the
application code. In the worst case scenario, the object being kept alive may contain
numerous other objects and so inadvertently keep them alive also.
The problem with this is that keeping objects alive after they are no longer needed will
unnecessarily increase the memory footprint of the application, in some cases, with
dramatic and irreversible consequences, leading to an OutOfMemoryException being thrown.
It is therefore essential that we detach our event handlers from the events that they are
subscribed to in objects that we have no further use for before trying to dispose of them.
There is however, an alternative method that we can use to avoid this situation. In the .NET
Framework, there is a WeakReference class and it can be used to remove the hard
references caused from attaching event handlers to events using the traditional method.
The basic idea is that the class that raises the event should maintain a collection of
WeakReference instances and add to it each time another class attaches an event handler to
the event. Let’s update our ActionCommand class from earlier to use this WeakReference
class now:
using System;
using System.Collections.Generic;
using System.Windows.Input;
namespace CompanyName.ApplicationName.ViewModels.Commands
{
public class ActionCommand : ICommand
{
private readonly Action<object> action;
private readonly Predicate<object> canExecute;
private List<WeakReference> eventHandlers = new
List<WeakReference>();
public ActionCommand(Action<object> action) : this(action,
null) { }
public ActionCommand(Action<object> action,
Predicate<object> canExecute)
{
if (action == null) throw new ArgumentNullException(“The
action
input parameter of the ActionCommand constructor cannot be
null.“);
this.action = action;
this.canExecute = canExecute;
}

public event EventHandler CanExecuteChanged
{
add
{
eventHandlers.Add(new WeakReference(value));
CommandManager.RequerySuggested += value;
}
remove
{
if (eventHandlers == null) return;
for (int i = eventHandlers.Count - 1; i >= 0; i–)
{
WeakReference weakReference = eventHandlers[i];
EventHandler handler = weakReference.Target as
EventHandler;
if (handler == null || handler == value)
{
eventHandlers.RemoveAt(i);
}
}
CommandManager.RequerySuggested -= value;
}
}
public void RaiseCanExecuteChanged()
{
eventHandlers.ForEach(
r => (r.Target as EventHandler)?.Invoke(this, new
EventArgs()));
}
public bool CanExecute(object parameter)
{
return canExecute == null ? true : canExecute(parameter);
}
public void Execute(object parameter)
{
action(parameter);
}
}
}
We start by adding a declaration of our new collection containing objects of type
WeakReference to the pre-existing fields. The two constructors remain unchanged, but when
attaching handlers in the CanExecuteChanged event, we now wrap the event handling
delegate in a WeakReference object and add it to the collection. We still need to pass the
references to the handlers that get attached through to the RequerySuggested event of the
CommandManager class as before.
When an event handler is removed, we first double check that our WeakReference collection
is not null and simply return control to the caller if it is. If not, we use a for loop to iterate
through the collection in reverse, so that we can remove items with affecting the loop index.
We attempt to access the actual event handler from the Target property of each

WeakReference object in turn, converting it to the base type EventHandler using the as
keyword. We then remove the WeakReference instance if its event handler reference is
either null, or matches the handler being removed.
Note that a null reference in the Target property would be the result of an event handler
from a class that has been disposed of by the garbage collector. As before, we then also
detach the event handler from the CommandManager.RequerySuggested event.
Finally, we need to update our RaiseCanExecuteChanged method to use our new collection
of WeakReference objects. In it, we again iterate through each instance in the collection
using our ForEach Extension method and after checking if its Target property is null using
the null conditional operator, call it using the delegate’s Invoke method.
So, the idea here is that we no longer directly hold on to any references to attached event
handlers and are therefore free to dispose of those classes at any point without fear of
them being kept alive unnecessarily.

Summary
In this chapter, we explored a number of options that we can use to increase the
performance of our WPF applications. As we have now seen, this is more a case of making
a large number of little changes to gain an overall noticeable performance benefit.
We saw that we can utilize the graphics rendering power of our computer’s graphics card
and declare our resources more efficiently. We investigated ways to improve our
application’s performance using lighter weight UI controls and more efficient methods of
rendering drawings, images and text. We continued and also found how to data bind,
display large objects and collections and handle events with improved performance.
In the next chapter, we will investigate the final requirement for all professional applications
- deployment. In it, we will first cover the older method, using the Windows Installer
software and then progress to investigate the more common and up-to-date method, using
ClickOnce functionality.

Chapter 11. Deploying Your Masterpiece
Application
So, we’ve designed and constructed our application framework, resources and managers,
added our Models, Views, and View Models and after completing the development of our
application, now it’s time for deployment. In this chapter, we’ll be looking at an overview of
the three main methods of deploying WPF applications.
We’ll start by investigating the original Windows Setup Project method, move on to
discover the newer InstallShield Limited Edition Project method and then progress to
examine the preferred ClickOnce technology.
Installing Windows applications
In days gone by, creating a Setup and Deployment project in Visual Studio was a
confusing and complicated process. However, as with just about everything in the .NET
Framework, successive updates over the years have resulted in ever improved creation
methods for these projects.
The latest deployment technologies are simpler to use and provide an easily
understandable method of performing the same steps as the earlier technologies. However,
in older versions of Visual Studio, we might only have access to the older Visual Studio
Installer project types, so let’s first investigate the standard Setup Project.
After adding a Setup Project to the solution, a page opens up showing the filesystem on
the target computer. In this File System Editor page, we can specify what we would like to

install and where. The page is divided into two, with a tree view of the folders to be
installed on the users’ computers on the left and their folder contents on the right. By
default, the left pane contains the Application, Desktop and Program Files folders.
If we would prefer to use other pre-defined locations, such as the Fonts, Favorites, or the
Common Files folders for example, then we can right-click on the background of these
panes and select the Add Special Folder option. Typically, we would add a standard folder
with our company’s name into the User’s Programs Menu folder and add a further folder
named after our application into that.
However, if we want to install our application as a 64 bit application, then we’ll need to use
this option to add the 64 bit Program Files folder to install into. To do so, we need to right-
click on the File System on Target Machine item at the top of the tree view, select the
Add Special Folder option and then select the Program Files (64-bit) Folder item.
Note that we should only perform this step if we want to have a 64 bit installation. We then
need to set the project output of our startup project to the folder in the left pane that
represents our installation folder, whether 32 or 64 bit.
We’ll need to right-click on that folder and select the Add option and then the Project
Outputs option from the contextual menu and then select the Primary Output option that
relates to our CompanyName.ApplicationName project. After doing so, we’ll see a copy of the
executable and other dependent files from its bin folder being included in our selected
application folder.
Next, we can create a shortcut to our application on the machine that it was installed on, by
right-clicking the icon for the project output in the right pane and selecting the Create
Shortcut to Primary output from CompanyName.ApplicationName (Active) option from
the menu.
We need to name it the same as our application name and set an icon for it, which we can
do in its Properties window. We can then click and drag, or copy and paste it to the User’s
Desktop folder, or to whichever folder we want the shortcut to appear in.
In addition to the executable and shortcut files, we can right-click a folder in the left pane
and select the Add option and then the Folder and/or File options from the contextual menu
and choose any other files that we may need to install on the user’s computer. Once we
have finished configuring the File System Editor, we can right-click on the project node in
the Solution Explorer and select another page to edit from the View menu.
The Registry Editor page is next and enables us to make entries in the Windows Registry
of the host computer. The left window pane acts as the registry view of the target computer
and we can use it in the same way as the Registry Editor to add new keys. This page also
allows us to import registry keys from a .reg file if we right-click on an empty space and
select Import.
The File Types Editor page follows in the View menu and enables us to associate any
custom file types that we may have created with our application. In doing so, after
installation Windows will then open our application whenever a file of one of the types
specified in this page are clicked.
The Setup Project enables us to display a number of default dialogs during installation,

such as welcome, confirmation and completion dialogs, and so on. It also provides the
ability to reorder, or remove these default dialogs, or add new ones from a pre-defined list.
Each dialog provides an image field and different options, such as whether a progress bar
should be displayed, or what text to display at different stages of the installation. This is
achieved in the User Interface page.
The Custom Actions Editor page enables us to specify assemblies that contain code in a
particular form, that can be run after the application has been installed. These actions could
be anything, such as popping up a small form and providing the user with some
configuration options, or simply opening a particular web page after installation has
completed.
The final option in the View menu of the Setup Project opens the Launch Conditions
Editor page. Here, we can specify prerequisite conditions that must be satisfied in order for
the application to be installed. For example, we might require a particular version of the
.NET Framework to be installed, or the host computer to have a particular registry key
setting.
Once the project pages have all been appropriately completed, we just need to build the
Setup and Deployment project to generate the setup files. However, we need to ensure
that we build it correctly, dependent upon the selections that we made in the File System
Editor page.
For example, if we wanted to have a number of setup projects, let’s say including 32 bit and
64 bit installations, then we need to only build the 32 bit version of the Setup Project in the
32 bit solution platform and only build the 64 bit version in the 64 bit solution platform.
We can do this in the Configuration Manager in Visual Studio, which we can open from
the last option in either the solution configuration or solution platform drop-down controls. If
the x86 and x64 solution platforms do not already exist, we can add them by selecting the
<New…> option from the solution platform drop-down control in the Configuration
Manager dialog window.
To add the new solution platforms in the New Solution Platform dialog that opens, type
either x86 or x64 in the Type or select the new platform field, select the <Empty> option
from the Copy settings from drop-down control and ensure that the Create new project
platforms tick box is checked.
Once we have these two solution platforms, we can select them one at a time in the Active
solution platform drop-down control in the Configuration Manager dialog window and tick
and untick the relevant setup projects.
Here is a screenshot of the x86 solutions selected:

Here is a screenshot of the x64 solutions selected:

Note that we must select Release in the solution configuration drop-down and then build our
project to generate the setup files. If we have setup our build configuration correctly, then
building the x86 solution platform will generate the 32 bit setup files and building the x64
solution platform will generate the 64 bit setup files.
It can be useful to uncheck the Build tick boxes for our deployment projects on all solution
platforms when the Active solution configuration is set to Debug. Doing this will stop the
deployment files from being regenerated every time that the solution is built while debugging
and will therefore save time during any future development.
To add a setup project in a modern version of Visual Studio, we need to select the
InstallShield Limited Edition Project from the Setup and Deployment project type in the
Other Project Types category in the left-hand pane of the Add New Project dialog
window.

Note that this project type is already included with all paid versions of Visual Studio, but
those who are using a free version may be directed to a website to download this
functionality upon selection of the project type.
Once installed and the project has been successfully added, a help wizard, or Project
Assistant window as InstallShield like to call it, will be opened in Visual Studio to aid the
process of configuring the installation project. It walks us through the various tasks that we
may need to perform when creating our installer, page by page.
Each page is divided into two window panes; the right pane contains the various fields that

we will edit to set our required specifications for the deployment and the left pane contains
additional options and contextual help topics, relevant to each page.
The first page of the Project Assistant is the Application Information page, where we
can provide general information about the application, such as the company name and
website, the application name and version and the icon to display with the application.
The Installation Requirements page enables us to select one or more particular operating
systems that our application is compatible with. In addition to this, we can also specify that
our application has a dependency from a pre-existing list of third-party software, such as
Adobe Reader, various versions of the .NET Framework and a number of Microsoft
products.
While this list is short, it does contain the most likely pre-requisite software titles. However,
there are a couple of additional options, one of which enables us to create custom
installation requirements. Upon clicking on this option, the System Search Wizard opens
and lets us search for additional installation requirements, either by folder path, registry key,
or by .ini file value, and enables us to choose what happens if the new requirement is not
met during the installation process.
The Application Files page is next and in it, we can add any required application files to
the installation. The page is divided into two, with a tree view of the folders to be installed
on the users’ computers on the left and the folder contents on the right. The left pane
contains a list of the most commonly used pre-defined folders, such as the App Data,
Common and Program Files folders.
If we need to use other pre-defined locations, such as the Desktop, Favorites, or the My
Pictures folders for example, then we can right-click on an item in this pane and select the
Show Predefined Folder option. In fact, if we want to install our application as a 64 bit
application, then we’ll need to use this option to add the 64 bit Program Files folder, in a
similar way to the Setup Project.
In order to do this, we can right-click on the Destination Computer item at the top of the
tree view, select the Show Predefined Folder option and then select the
ProgramFiles64Folder item. We would then need to set the project output of our startup
project to the folder in the left pane that represents our installation folder. Note that it will be
suffixed with [INSTALLDIR] and in our case, will be named ApplicationName.
We should click the Add Project Outputs button and select the Primary Output option
that relates to our CompanyName.ApplicationName project to include a copy of the DLLs and
other dependent files from its bin folder in the deployment. We can right-click the added
output item to select further properties if required, or if we are using COM objects in our
application.
Next up is the Application Shortcuts page, where we can control which custom shortcuts
the installation will include on the users’ computer. Note that default shortcuts will
automatically be added for the executable files that we have specified, but this page
enables us to delete these, as well as add new ones, or even specify uninstallation
shortcuts, or alternative icons to use.
The Application Registry page follows and enables us to make entries in the Windows
Registry of the computer that our application is being installed on. The left window pane

mirrors the registry view of the destination computer and we can use it in the same way to
add new keys. This page also allows us to import registry keys from a .reg file and open
the registry editor on the source computer.
The last page is the Installation Interview page, where we can specify which dialog
screens are displayed to the user during the installation. Here, we can optionally upload an
End User License Agreement file in the Rich Text Format (RTF) file format to display to
and require the user to agree to.
Additionally, we can prompt the user to enter their username and company name and
provide them with options to select the installation location and whether the application
should open after the installation is complete. We can also specify custom images to be
displayed in these dialog windows from this page.
Once the project assistant pages have all been appropriately completed, we just need to
build the setup and deployment project to generate the setup files. However, we need to
ensure that we build it correctly, dependent upon the selections that we made in the project
assistant.
When using and focusing the InstallShield Limited Edition Project in the Solution
Explorer in Visual Studio, we get an extra InstallShield LE menu item and in it, we can find
an Open Release folder… option. Clicking this option will open a folder window, showing
the setup project folder, in which we can find the installation files to distribute to the users.

Utilizing ClickOnce functionality
ClickOnce is an application deployment technology that enables us to deploy applications
that can be installed, run and updated with minimal interaction from the end user. In fact, the
name ClickOnce comes from the ideal scenario, where each application could be installed
with a single click.
Each ClickOnce application is deployed into its own self-contained area on the host
computer, with no access to other applications, rather than in one of the standard program
files folders that the other deployment technologies use. Furthermore, they only grant the
exact security permissions required by the application and so, can generally also be
installed by non-administrative users.
Another benefit of using ClickOnce is that it enables applications to be installed either from
a web page, a network folder, or from physical media. We can also specify that
applications installed using ClickOnce should check for updates at regular periods and can
be easily updated by the end user, without requiring an administrator to be present.
ClickOnce deployments contain an application manifest and a deployment manifest. The
application manifest contains details of the application, such as its dependencies, required
security permissions, and the location where updates will be available. The deployment
manifest contains details of the deployment, such as the location of the application manifest
and the target version of the application.
ClickOnce is now the preferred method of deploying applications and is built right into the
project properties of our startup project. We can open the properties window by either
right-clicking on the CompanyName.ApplicationName project in the Solution Explorer and
selecting the Properties option, by opening the project node and double clicking on the
Properties item, or by selecting the project node and pressing the Alt + Enter keys on the
keyboard together.
In the project properties window, we can find the ClickOnce configuration fields in the
Publish tab. In this tab, we can set the location of the publishing folder to a network shared
folder or FTP server. This represents the location that files will be published to. Optionally,
we can also specify the location that users will install the application from, if that will be
different.
We can dictate that the installation mode should make the application available online only,
like a web application, or offline as well, like a typical desktop application. In this section,
we also have the Application Files button that opens a dialog window where we can
specify which additional files to include in the deployment.
All files from the solution that currently get built into the bin folder will be included by
default, but we can exclude them if we prefer. Alternatively, we can add new files from the
Solution Explorer by setting their Build Action to Content in the Properties window. We
can also specify whether any executable files are prerequisites, or whether any other file
types are data files. However this is set for us automatically and we do not need to make
changes here, unless we have specific requirements.
Next, we see the Prerequisites button, which opens a dialog window that enables us to
create a setup program to install any prerequisite components that we may have, such as

the .NET Framework and the Windows Installer software. If the users’ computers do not
already have the required prerequisites installed, we can specify where the installer should
access them from. This dialog is also automatically populated according to the
requirements of the application.
In order to specify that the installed applications should check for updates, we can tick the
The application should check for updates checkbox in the dialog that opens after
clicking the Updates button in the Publish tab. We can also specify whether this occurs
before or after the application starts, or after a certain period of time.
In the Application Updates dialog window, we can also stipulate that the application should
be mandatorily updated to a particular version by ticking the Specify a minimum required
version for this application checkbox and setting the version. Additionally, we can specify
a further location that updates can be accessed from, if it would be different to the publish
location.
Finally, in the Install Mode and Settings section, we come to the Options button, which
opens the Publish Options dialog window, where we can specify details such as the
publisher and product names, deployment and manifest settings and associate our
applications with our custom file types, so that it will open when those file types are clicked.
The Deployment options enable us to specify a web page that users can use to download
and install our ClickOnce application from, although if we enter default.html, we can use
the default page that is generated for us. We can also specify whether the web page
should automatically open, or whether the uploaded files should be verified after publishing
the application.
The final section in the Publish tab is the Publish Version section, where we can specify
the current version of the application. Rather than update this manually each time we
publish, we can optionally tick the Automatically increment revision with each publish
checkbox to update the revision for us.
In this section, we have two publishing options. The Publish Wizard button opens a multi-
page dialog window that walks us through many of the more essential options described
previously and ends with publishing the application. While this is useful for the first time that
we publish the application, we tend to use the other option, the Publish Now button after
that, which simply publishes the application.
Securing deployments
On the Security tab of the project properties window, we can specify the security
permissions that our application requires. To do so, we can tick the Enable ClickOnce
security settings checkbox and select whether our application is a full or partial trust
application.
For a typical desktop application, it is common to specify that it is a full trust application, but
otherwise we can specify just the trust level that we require. Note that unless the
application publisher is set as a trusted publisher on the end user’s computer, they might be
required to grant any required permissions during installation.
If we specify that our application is a partial trust application, then we can either select from
pre-configured zones that contain specific groups of permissions, or select custom

permissions, in which case, we can manually specify our required permissions directly in the
application manifest file.
Note that even if we have specified our application as a partial trust application, we usually
have full trust when developing. In order to develop using the same permissions that our
application requires and therefore see the same errors as the users, we can click the
Advanced button and tick the Debug this application with the selected permission set
checkbox.
On the Signing tab of the project properties window, we can optionally digitally sign the
ClickOnce manifests by ticking the Sign the ClickOnce manifests checkbox. If we have a
valid certificate that has been persisted in the computer’s certificate store, then we can
select it to sign the ClickOnce manifests using the Select from Store button.
Alternatively, if we have a Personal Information Exchange (PFX) file, we can sign the
manifests with it by clicking on the Select from File button and selecting it in the file
explorer that opens. If we don’t currently have a valid certificate, we can optionally create
one for testing purposes by clicking on the Create Test Certificate button.
Note however, that a test certificate should not be deployed with a production application as
they do not contain verifiable information about the publisher. When installing the ClickOnce
application with a test certificate, users will be informed that the publisher cannot be verified
and asked to confirm whether they really want to install the application. For the peace of
mind of the end users, a real certificate should be used and a copy stored in their Trusted
Publishers Certificate Store.
We can also optionally sign the assembly by ticking the Sign the assembly checkbox and
selecting a Strong Name Key (SNK) file from the associated drop-down control. If we
haven’t previously selected one, we can add a new one from the same drop-down control.
This completes the summary of the configuration pages used for a ClickOnce deployment.
They provide practically the same settings as the other deployment technologies, except
those to do with the location of the installed files and the security permissions that may be
required to install. Let’s now look at how we can safely store files on the host computer in
non-full trust applications.
Isolating storage
One of the reasons why ClickOnce can be installed directly by the end users, without the
need for administrator assistance is because it is installed into a self-contained eco system,
separate from all other programs and in general, isolated from the rest of the user’s
computer.
When we have a requirement to store data locally, we can run into security problems if we
have not specified our application as a full trust application. In these situations, we can take
advantage of isolated storage, which is a data storage mechanism that abstracts the actual
location of the data on the hard drive, which remains unknown to both users and
developers.
When we use isolated storage, the actual data compartment where the data is stored is
generated from some aspects of each application, so that it is unique. The data
compartment contains one or more isolated storage files called stores, which reference

where the actual data is stored. The amount of data that can be stored in each store can
be limited by code in the application.
The actual physical location of the files will differ, depending upon the operating system
running on the user’s computer and whether the store has roaming enabled or not. For all
operating systems since Vista, the location is in the hidden AppData folder in the user’s
personal user folder. Within this folder, it will either be found in the Local or Roaming folders,
depending on the store’s settings.
<SYSTEMDRIVE>\Users<username>\AppData\Local
<SYSTEMDRIVE>\Users<username>\AppData\Roaming
We can store any type of file in isolated storage, but as an example, let’s take a look at
how we could utilize it to store text files:
using System.IO;
using System.IO.IsolatedStorage;
namespace CompanyName.ApplicationName.Managers
{
public class HardDriveManager
{
private IsolatedStorageFile GetIsolatedStorageFile()
{
return IsolatedStorageFile.GetStore(IsolatedStorageScope.User
|
IsolatedStorageScope.Assembly |
IsolatedStorageScope.Domain,
null, null);
}
public void SaveTextFile(string filePath, string fileContents)
{
try
{
IsolatedStorageFile isolatedStorageFile =
GetIsolatedStorageFile();
using (IsolatedStorageFileStream isolatedStorageFileStream
=
new IsolatedStorageFileStream(filePath,
FileMode.OpenOrCreate,
isolatedStorageFile))
{
using (StreamWriter streamWriter =
new StreamWriter(isolatedStorageFileStream))
{
streamWriter.Write(fileContents);
}
}
}
catch { /Log error/ }
}
public string ReadTextFile(string filePath)
{
string fileContents = string.Empty;
try

{
IsolatedStorageFile isolatedStorageFile =
GetIsolatedStorageFile();
if (isolatedStorageFile.FileExists(filePath))
{
using (IsolatedStorageFileStream
isolatedStorageFileStream =
new IsolatedStorageFileStream(filePath, FileMode.Open,
isolatedStorageFile))
{
using (StreamReader streamReader =
new StreamReader(isolatedStorageFileStream))
{
fileContents = streamReader.ReadToEnd();
}
}
}
}
catch { /Log error/ }
return fileContents;
}
}
}
As with the other manager classes, we declare the HardDriveManager class in the
CompanyName.ApplicationName.Managers namespace. In the private
GetIsolatedStorageFile method, we obtain the IsolatedStorageFile object that relates
to the isolated storage store that we will save the user’s data in, by calling the GetStore
method of the IsolatedStorageFile class.
This method has a number of overloads that enable us to specify the scope, application
identity, evidence and evidence types, with which to generate the unique isolated storage
file. In this example, we use the overload that takes the bitwise combination of the
types, which we simply pass null for.
The scope input parameter here is interesting and requires some explanation. Isolated
storage is always restricted to the user that was logged on and using the application when
the store was created. However, it can also be restricted to the identity of the assembly, or
to the assembly and application domain together.
When we call the GetStore method, it obtains a store that corresponds with the passed
enumeration members, this acquires a store that can be shared between applications that
use the same assembly, when used by the same user. Typically, this is allowed under the
Intranet security zone, but not the Internet zone.
members, this acquires a store that can only be accessed by the user, when running the
application that was used to create the store. This is the default and most common choice
for most applications and so, these are the enumeration members that were used in our
example.
Note that if we had wanted to enable the user to use roaming profiles, but still be able to

access their data from their isolated storage file, then we could have additionally included
the Roaming enumeration member with the other members.
Returning to the HardDriveManager class now, in the SaveTextFile method, we first call the
GetIsolatedStorageFile method to obtain the IsolatedStorageFile object. We then
initialize an IsolatedStorageFileStream object with the filename specified by the filePath
input parameter, the OpenOrCreate member of the FileMode enumeration and the storage
file object.
Next, we initialize a StreamWriter object with the IsolatedStorageFileStream variable and
write the data from the fileContents input parameter to the file specified in the stream
using the Write method of the StreamWriter class. Again, we enclose this in a try…catch
block and would typically log any exceptions that might be thrown from this method, but
omit this here for brevity.
In the ReadTextFile method, we initialize the fileContents variable to an empty string and
then obtain the IsolatedStorageFile object from the GetIsolatedStorageFile method. We
verify that the file specified by the filePath input parameter actually exists before
attempting to access it.
We then initialize an IsolatedStorageFileStream object with the filename specified by the
filePath input parameter, the Open member of the FileMode enumeration and the isolated
storage file.
Next, we initialize a StreamReader object with the IsolatedStorageFileStream variable and
read the data from the file specified in the stream into the fileContents input parameter
using the Read method of the StreamReader object. Once again, this is all enclosed in a
try…catch block and finally, we return the fileContents variable with the data from the
file.
In order to use it, we can expose a reference to the new HardDriveManager class from our
BaseViewModel class:
public HardDriveManager HardDriveManager
{
get { return new HardDriveManager(); }
}
We can then use it to save files to, or read files from isolated storage from any View
Model:
HardDriveManager.SaveTextFile(“UserPreferences.txt”,
“AutoLogIn:True”);
string preferences =
HardDriveManager.ReadTextFile(“UserPreferences.txt”);
Realistically, if we were to save user preferences in this way, they would typically be in an
XML file, or in another format that is more easily parsed. However, for the purposes of this
example, a plain string will suffice.
As well as saving and loading files in an isolated storage store, we can also delete them
and add or remove folders to better organize the data. We can add further methods to our

HardDriveManager class, to enable us to manipulate the files and folders from within the
user’s isolated storage store. Let’s take a look at how we can do this now:
public void DeleteFile(string filePath)
{
try
{
IsolatedStorageFile isolatedStorageFile =
GetIsolatedStorageFile();
isolatedStorageFile.DeleteFile(filePath);
}
catch { /Log error/ }
}
public void CreateFolder(string folderName)
{
try
{
IsolatedStorageFile isolatedStorageFile =
GetIsolatedStorageFile();
isolatedStorageFile.CreateDirectory(folderName);
}
catch { /Log error/ }
}
public void DeleteFolder(string folderName)
{
try
{
IsolatedStorageFile isolatedStorageFile =
GetIsolatedStorageFile();
isolatedStorageFile.DeleteDirectory(folderName);
}
catch { /Log error/ }
}
Quite simply, the DeleteFile method accesses the IsolatedStorageFile object from the
GetIsolatedStorageFile method and then calls its DeleteFile method, passing in the
name of the file to delete, which is specified by the filePath input parameter, within
another try…catch block.
Likewise, the CreateFolder method obtains the IsolatedStorageFile object from the
GetIsolatedStorageFile method and then calls its CreateDirectory method, passing in the
name of the folder to create, specified by the folderName input parameter, within a
try…catch block.
Similarly, the DeleteFolder method acquires the IsolatedStorageFile object by calling the
GetIsolatedStorageFile method and then calls its DeleteDirectory method, passing in the
name of the folder to delete, that is specified by the folderName input parameter, within
another try…catch block.
Now, let’s adjust our previous example to demonstrate how we can use this new
functionality:
HardDriveManager.CreateFolder(“Preferences”);
HardDriveManager.SaveTextFile(“Preferences/UserPreferences.txt”,
“AutoLogIn:True”);

string preferences =
HardDriveManager.ReadTextFile(“Preferences/UserPreferences.txt”);
HardDriveManager.DeleteFile(“Preferences/UserPreferences.txt”);
HardDriveManager.DeleteFolder(“Preferences”);
In this extended example, we first create a folder named Preferences in the isolated
storage store and then save the text file in that folder, by prefixing the filename with the
name of the folder and separated from the name with a forward slash.
At a later stage, we can then read back the contents of the file by passing in the same file
path to the ReadTextFile method. If we need to clear up the store afterwards, or if the file
was temporary, we can delete it by passing the same file path to the DeleteFile method.
Note that we must first delete the contents of a folder in the store before we can delete the
folder itself.
Also note that we can create subdirectories in the isolated storage store, by chaining their
names in the file path. For example, we can create a Login folder in the folder named
Preferences by simply appending the subdirectory name to the end of the parent folder
name and separating them with a forward slash again.
HardDriveManager.CreateFolder(“Preferences”);
HardDriveManager.CreateFolder(“Preferences/Login”);
HardDriveManager.SaveTextFile(“Preferences/Login/UserPreferences.tx
t”,
“AutoLogIn:True”);

Accessing application versions
In .NET, an application has a number of different versions and so, we have a number of
alternative ways to access them. The version number that we discussed earlier and is
displayed in the Publish Version section of the Publish tab of the project properties can
be found using the ApplicationDeployment class from the System.Deployment DLL.
using System.Deployment.Application;
private string GetPublishedVersion()
{
if (ApplicationDeployment.IsNetworkDeployed)
{
return ApplicationDeployment.CurrentDeployment.CurrentVersion.
ToString();
}
return “Not network deployed”;
}
Note that we need to verify that the application has actually been deployed before we can
access the CurrentVersion property of the ApplicationDeployment class, otherwise an
InvalidDeploymentException will be thrown. This means that we cannot attain the
published version while debugging our WPF applications and so, should return some other
value instead in these instances.
In order to view the remaining application versions, we first need to access the assembly
that we want to know the version of. The code that we use to access the assembly will
depend on where in the code we currently are. For example, we typically want to display
the version of the startup assembly, but we may want to access it from a View Model in the
ViewModels project instead.
We have a number of ways of accessing assemblies, depending on where they are in
relation to the calling code. If we want to access the startup assembly from the startup
project, the we can use the Assembly.GetExecutingAssembly method, after adding using
statements for the following namespaces:
using System.Diagnostics;
using System.Reflection;
To access the same assembly from a different project, we can use the
Assembly.GetEntryAssembly method. Alternatively, we can access the startup project’s
assembly from a different project if that project was called from the startup assembly, using
the Assembly.GetCallingAssembly method. For the remaining examples here, we’ll use the
GetEntryAssembly method.
In addition to the published version, we may also need to access the application’s assembly
or file versions. The assembly version that we can set in the Assembly Information dialog
window, which is accessible from the Application tab of the project properties window can
be accessed from the assembly, using the following code:
string assemblyVersion =

Assembly.GetEntryAssembly().GetName().Version.ToString();
The assembly version is used by the .NET Framework to load and link references to other
assemblies at build and runtime. This is the version that is embedded when adding
references to our projects in Visual Studio and if an incorrect version is found during a build,
then an error will be raised.
Note that we can also set this value using the assembly level AssemblyVersionAttribute
class in the AssemblyInfo.cs file of the project, which can be found in the Properties node
of the project in the Solution Explorer.
Instead of converting the returned Version object to a string directly, we may prefer to
access the individual components that make up the version number. They are comprised of
the Major, Minor, Build and Revision component values. We could then chose to just output
the Major and Minor components, along with the product name for example:
Version assemblyVersion =
Assembly.GetEntryAssembly().GetName().Version;
string productName = FileVersionInfo.GetVersionInfo(
Assembly.GetEntryAssembly().Location).ProductName;
string output = $“{productName}: Version {version.Major}.
{version.Minor}“;
If we need the file version, which is used for non ClickOnce deployments, we can pass the
location of the assembly to the GetVersionInfo method of the FileVersionInfo class, as
shown in the preceding code, in the product name example, but access the FileVersion
property instead.
string fileVersion = FileVersionInfo.GetVersionInfo(
Assembly.GetEntryAssembly().Location).FileVersion;
Note that we can also set this value in the Assembly Information dialog window, or by
using the assembly level AssemblyFileVersionAttribute class in the AssemblyInfo.cs file
of the project. This version can be seen in the Details tab of the file properties dialog
window in Windows Explorer.

The product version that the assembly is distributed with can be accessed in a similar way:
string productVersion = FileVersionInfo.GetVersionInfo(
Assembly.GetEntryAssembly().Location).ProductVersion;
Note that this version can also be seen in the Details tab of the file properties dialog
window in Windows Explorer, along with the product name that we accessed earlier. Also
note that in a WPF application, this value typically comes from the assembly file version.

Summary
In this chapter, we explored a number of different ways to deploy our WPF applications.
We looked over the older Setup Project type and the InstallShield Limited Edition
Project type, but focused primarily on the newer ClickOnce technology. We investigated
how ClickOnce deployments are made and how we can safely store and access data in
isolated storage. We ended by looking at a number of ways to access the various
application versions available to us in .NET.
In the final chapter, we’ll take a look at a summary of what has been covered throughout
this book and investigate what you can do next to continue this journey. We’ll suggest a few
possible ways that you could extend our application framework further and what you can do
to advance your application development further in general.

Chapter 12. What Next?
In this book, we discovered the MVVM architectural pattern and explored the process of
developing a WPF application, while taking advantage of this pattern’s Separation of
Concerns and adhering to its principals. We investigated a number of different ways of
communicating between the various application layers and structuring our code base.
Importantly, we considered a variety of ways of debugging our WPF applications and
tracking down our coding problems. In particular, we revealed some tips and tricks to help
us to identify the causes of our data binding errors. In addition, we also learnt how viewing
trace information can help us to detect problems, even after our applications have been
deployed.
We moved on to investigate the benefit of utilizing an application framework and began
designing and developing our own. We structured it in a way that did not tie our framework
to any particular feature or technology and experimented with a variety of ways to
encapsulate our required functionality.
We devoted a whole chapter to the essential art of data binding and took a detailed look at
the creation of Dependency Properties and Attached Properties. We looked at setting
Dependency Property metadata and were introduced to the crucial Dependency Property
Setting Precedence List. We then covered both standard and hierarchical data templates
and studied some interesting data binding examples.
Investigating the rich inheritance hierarchy of the built-in WPF controls enabled us to see
how their functionality is built up from each successive base class in the hierarchy. This in
turn enabled us to see that some controls are better to use in some situations than others.
We also found out how to customize the built-in controls and considered how best to make
our own controls.
While the animation possibilities in a WPF application are practically endless, we
investigated the more usable options, primarily focusing on the syntax used in XAML. We
then added animation functionality directly into our application framework, where it could be
used with little effort, on the part of the developers.
After turning our attention to the look of our applications, we investigated a number of
techniques, such as borderless windows and adding shadows and glowing effects to more
advanced methods for making our application stand out from the crowd. We also
incorporated animations into our everyday controls, in order to bring about a sense of
exclusivity to our applications.
We thoroughly investigated the data validation options that the .NET Framework offers us,
primarily concentrating on the two available validation interfaces, and exploring a number of
different ways of implementing them. We probed advanced techniques, such as multilevel
validation and using data annotation attributes, and then added a complete validation
system into our application framework.
We further extended our application framework with an asynchronous data operation
system that was combined with a complete user feedback component, including an
animated feedback display mechanism. We continued with investigating how we can
provide in-application help and user preferences and implement work-heavy functions to

save the users time and effort.
We also explored a number of options that we can use to increase the performance of our
WPF applications, from declaring our resources more efficiently to using lighter weight
controls and more efficient methods of rendering drawings, images and text. We saw more
performant methods of data binding and discovered the importance of detaching event
handlers.
Finally, we investigated the last task in any professional application’s development, its
deployment. We looked at a number of alternative methods, but primarily focused on the
most popular ClickOnce technology. We investigated how ClickOnce deployments are made
and how we can safely store and access data in isolated storage. We ended with a number
of ways to access the various application versions available to us in .NET.
Overall, we’ve covered a plethora of information that together, will enable us to create
efficient, visually appealing, highly usable and highly productive applications in WPF. What’s
more, we’ve now got our own application framework that we can reuse for each new
application that we create. So, what is next?
Turning attention to future projects
You could apply the concepts and ideas from this book to other areas and continue to
experiment and explore their effect in these new areas. For example, we’ve learnt about
Adorner objects, so you could use that new found knowledge to implement some visual
feedback for the common drag and drop functionality in the main window’s adorner layer.
You could then further extend this idea, using what you’ve discovered about Attached
Properties, and completely encapsulate this drag and drop functionality, enabling the
developers that utilize your application framework to make use of this feature in a property-
based manner.
For example, you could create a DragDropProperties class that declared Attached
Properties, such as IsDragSource, IsDragTarget, DragEffects, DragDropType and
DropCommand, and could be extended by your relevant Attached Property classes, such as a
ListBoxProperties class.
You could then declare a BaseDragDropManager class to be used in the DragDropProperties
class, that stitches everything together, by attaching and removing the appropriate event
handlers, starting the drag and drop procedure, updating the cursor via the drag and drop
effects as it moves across the screen and executing the ICommand object assigned to the
DropCommand Property.
This leads to a further area that could be extended. Not only can we handle UI events in
Attached Properties, but we can also combine them to perform more complex functionality.
For example, let’s say that we have an Attached Property of type string, named Label.
When this property is set, it could apply a particular ControlTemplate element from
resources to the current TextBox object’s Template property. This template could display
the text from this property in a secondary text element and therefore act as an internal
label. When the TextBox object has a value, the label text element could be hidden via an
IValueConverter implementation that extends our BaseVisibilityConverter class:
<TextBlock Text=“{Binding (Attached:TextBoxProperties.Label),

RelativeSource={RelativeSource AncestorType=TextBox},
FallbackValue=“}”
Foreground=“{Binding (Attached:TextBoxProperties.LabelColor),
RelativeSource={RelativeSource AncestorType=TextBox},
FallbackValue=#FF000000}” Visibility=“{Binding Text,
RelativeSource={RelativeSource AncestorType=TextBox},
Converter={StaticResource StringToVisibilityConverter},
FallbackValue=Collapsed}” … />
As shown in the preceding example, we could then declare another Attached Property,
named LabelColor, of type Brush, that specifies the color to be used by the Label Attached
Property when it is set. Note that if the LabelColor property is not set, then it will either use
its default value if set, or the value specified in the FallbackValue property.
Improving our application framework
Another area that you can continue to work on is customizing our application framework
further and adapting it to your individual requirements. With this in mind, you could continue
to build up a complete collection of customized controls with a particular look and feel in an
external resource file to use in all of your applications.
There are also many other examples provided throughout this book that could be easily
extended. For example, you could update our DependencyManager class to enable multiple
concrete classes to be registered for each interface.
Instead of using a Dictionary<Type, Type> object to store our registrations, you could
define new custom objects. You could declare a ConcreteImplementation struct that has a
Type property and an object array to hold any constructor input parameters that may be
required for its initialization:
public ConcreteImplementation(Type type,
params object[] constructorParameters)
{
Type = type;
ConstructorParameters = constructorParameters;
}
You could then declare a DependencyRegistration class that you could use to pair the
interface type with the collection of concrete implementations:
public DependencyRegistration(Type interfaceType,
IEnumerable<ConcreteImplementation> concreteImplementations)
{
if (!concreteImplementations.All(c =>
interfaceType.IsAssignableFrom(c.Type)))
throw new ArgumentException(“The System.Type object specified
by the
ConcreteImplementation.Type property must implement the
interface type
specified by the interfaceType input parameter.“,
nameof(interfaceType));
ConcreteImplementations = concreteImplementations;
InterfaceType = interfaceType;
}
In our DependencyManager class, you could change the type of the registeredDependencies
field to a collection of this new DependencyRegistration type. The current Register and

Resolve methods could then also be updated to use this new collection type.
Alternatively, you could include other common functionality that is contained within popular
Dependency Injection and Inversion of Control containers, such as automatic registering of
concrete classes to interfaces at assembly level. For this, you could use some basic
reflection:
using System.Reflection;
public void RegisterAllInterfacesInAssemblyOf<T>() where T : class
{
Assembly assembly = typeof(T).Assembly;
IEnumerable<Type> interfaces =
assembly.GetTypes().Where(p => p.IsInterface);
foreach (Type interfaceType in interfaces)
{
IEnumerable<Type> implementingTypes = assembly.GetTypes().
Where(p => interfaceType.IsAssignableFrom(p) &&
!p.IsInterface);
ConcreteImplementation[] concreteImplementations =
implementingTypes.
Select(t => new ConcreteImplementation(t, null)).ToArray();
if (concreteImplementations != null &&
concreteImplementations.Any())
registeredDependencies.Add(interfaceType,
concreteImplementations);
}
}
This method first accesses the assembly that contains the generic type parameter and then
gets a collection of the interfaces in that assembly. It then iterates through the interface
collection and finds a collection of classes that implements each interface, instantiating a
ConcreteImplementation element with each. Each match is added into the
registeredDependencies collection with its relating interface type.
In this way, you could pass any interface type from our Models, Managers and ViewModels
projects to automatically register all of the interfaces and concrete classes found inside
their assemblies. There is a clear benefit to doing this in larger applications, as it will mean
that you don’t have to manually register each type.
private void RegisterDependencies()
{
DependencyManager.Instance.ClearRegistrations();
DependencyManagerAdvanced.Instance.
RegisterAllInterfacesInAssemblyOf<IDataProvider>();
DependencyManagerAdvanced.Instance.
RegisterAllInterfacesInAssemblyOf<IUiThreadManager>();
DependencyManagerAdvanced.Instance.
RegisterAllInterfacesInAssemblyOf<IUserViewModel>();
}
Additionally, you could declare another method that registers all types found in the assembly
of the type specified by the generic type parameter T, where matches of implemented

interfaces are found. This could be used during testing, so that you could just pass any type
from the mock projects during testing, again saving time and effort.
DependencyManager.Instance.
RegisterAllConcreteImplementationsInAssemblyOf<MockUiThreadManager>
();
As with all serious development projects, there is a need to test the code that makes up the
code base. Doing so obviously helps to reduce the number of bugs in the application, but
also alerts us when existing functionality has been broken, while adding new code. They
also provide a safety net for refactoring, allowing us to continually improve our designs,
while ensuring that existing functionality is not broken.
Therefore, one area that you could improve in the application would be to implement a full
test suite. This book has explained a number of ways for us to swap out code during testing
and this pattern can be easily extended. If a manager class uses some sort of resource
that cannot be used during testing, then you can create an interface for it, add a mock class
and use the DependencyManager class to instantiate the relevant concrete implementation
during runtime and testing.
Another area from the book that could be extended relates to our AnimatedStackPanel
class. You could extract the reusable properties and animation code from this class to an
AnimatedPanel base class, so that it could service several different types of animated
panel.
As suggested in Chapter 6, Mastering Practical Animations, you could then further extend
the base class by exposing additional animation properties, so that users of your panel
could have more control over the animations that it provides. For example, you could add
alignment, direction, duration, and/or animation type properties to enable users of your
framework to use a wide variety of animation options.
These properties could be divided between the entry and exit animations, to enable
independent control over them. By providing a wide variety of these additional properties in
a base class, you can vastly simplify the process of adding new animated panels.
For example, you could add a new AnimatedWrapPanel, or perhaps an
AnimatedColumnPanel, by simply extending the base class and only have to implement the
two MeasureOverride and ArrangeOverride methods in the new panel.
Logging errors
In a number of places in the code examples in this book, you may have seen Log error
comments. In general, it is not only good practice to log errors, but it can also help you to
track down bugs and improve the overall user experience of the users of your applications.
The easiest place to log errors to would be an Errors database and the minimum useful
information fields that you’d want to store would include details of the current user, the time
it occurred, the exception message, the stack trace and the assembly or area that it
occurred in. This latter field can be found in the Module property of the exception’s
TargetSite property.
public Error(Exception exception, User createdBy)
{

Id = Guid.NewGuid();
Message = FlattenInnerExceptions(exception);
StackTrace = exception.StackTrace;
Area = exception.TargetSite.Module.ToString();
CreatedOn = DateTime.Now;
CreatedBy = createdBy;
}
Note the use of the custom FlattenInnerExceptions method that also outputs the
messages from any inner exceptions that the thrown exception may contain. One alternative
to building your own FlattenInnerExceptions method would be to simply save the
ToString output of the exception, which will also contain details of any inner exceptions that
it may contain, although it will also contain stack trace and other information as well.
Using online resources
As a final note, if you are not already familiar with the Microsoft Developer Network
(MSDN) website, you really should acquaint yourself with it. It is maintained for the
Microsoft developer community and includes everything from detailed APIs for their various
languages, and tutorial walkthroughs and code examples through to downloads of their
software.
questions arise over the various classes in the .NET framework. Should you not find your
required information in their APIs, then you can ask questions in their forums and quickly
receive answers from both the community and from Microsoft employees.
Another great developer resource is the Stack Overflow question and answer site for
development professionals, where I still answer questions when I can find the time. It can
community within seconds, it really is hard to beat and one of the best development forums
around.
All that remains now is for me to wish you well with your future application development and
your blossoming development careers.